iOS Popover segue documentation/tutorial?

whooleytoo

macrumors 604
Original poster
Aug 2, 2002
6,568
638
Cork, Ireland.
Maybe my Google skills are failing me, but I can't find any documentation or tutorials on how to create a popover segue in Storyboard. I've found several that create a popover programmatically, but none for Storyboard.

I tried creating a ViewController in the Storyboard, then a Popover segue to it. Link the segue's anchor to a view in the source scene (is that correct?). But when I trigger the segue, prepareForSegue: gets called, then... nothing.
 

Ron C

macrumors member
Jul 18, 2008
61
0
Chicago-area
I do have some code for a custom subclass of UISegue (or whatever it's called) that I'll post tomorrow when I'm on my computer instead of iPad.

In the meantime, verify that the segue.destinationViewController is what you want it to be, and maybe just for grins you can change it to a modal and see if that works. If it doesn't work there something is wrong in the storyboard,
 

whooleytoo

macrumors 604
Original poster
Aug 2, 2002
6,568
638
Cork, Ireland.
Thanks. I tried adding a button and doing a (non-conditional) popover segue from that and it worked fine. My problem was performing a segue from a button in a (custom)UITableViewCell; doesn't work for me; I get an error saying the outlet can't be compiled. If I do a conditional segue and trigger it from the cell's button, there's no error, but the popover doesn't appear either.

So, I can't see any way of performing a popover segue from a button in a cell, either directly or via performSegue: .... It was quite easy to do so via code, so I went that route instead. Thanks again.
 

Ron C

macrumors member
Jul 18, 2008
61
0
Chicago-area
Code and hint

A little more background. I'm not entirely sure popover segues work, and I couldn't find a simple way of doing a popover segue that would operate in the way I needed it to without building a custom UIStoryboardSegue subclass. This subclass doesn't do a lot, really, except REUSE your popover controller AND allow toggling.

Given that it became a custom subclass, I also couldn't get any custom information into it from the storyboard, so I put that code into the prepareForSegue: handler in the view controller.

This is what it looks like in Xcode:
Screen Shot 2012-06-08 at 7.44.31 AM.png

What that picture shows is a custom segue going from a bar button item to a navigation controller. It's a navigation controller because there's a sequence of table view controllers under that popover, but it can be any subclass of UIViewController.

Here's the code:

SinglePopoverSegue.h
Code:
//
//  SinglePopoverSegue.h
//  LTE-A Visualizer
//
//  Created by Ron Crocker on 1/24/12.
//  Copyright (c) 2012 Nokia Siemens Networks, LLC. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface SinglePopoverSegue : UIStoryboardSegue

@property (strong) UIPopoverController *popoverController;
@property (strong) UIBarButtonItem *barButtonItem;
@property (assign) UIPopoverArrowDirection popoverArrowDirections;
@property (assign) BOOL animated;
@property (assign) BOOL toggleMode;
@end
SinglePopoverSegue.m
Code:
//
//  SinglePopoverSegue.m
//  LTE-A Visualizer
//
//  Created by Ron Crocker on 1/24/12.
//  Copyright (c) 2012 Nokia Siemens Networks, LLC. All rights reserved.
//

#import "SinglePopoverSegue.h"

@implementation SinglePopoverSegue

@synthesize popoverController;
@synthesize popoverArrowDirections;
@synthesize animated;
@synthesize barButtonItem;
@synthesize toggleMode;

-(id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination
{
    if ((self = [super initWithIdentifier:identifier
                                   source:source
                              destination:destination])) {
        self.popoverArrowDirections = UIPopoverArrowDirectionAny;
        self.popoverController = nil;
        self.animated = YES;
        self.barButtonItem = nil;
        self.toggleMode = YES;
    }
    return self;
}

-(void)perform
{
    if (!self.popoverController.popoverVisible) {
        self.popoverController.contentViewController = self.destinationViewController;
        
        [self.popoverController presentPopoverFromBarButtonItem:self.barButtonItem
                                       permittedArrowDirections:self.popoverArrowDirections
                                                       animated:self.animated];
    } else if (self.toggleMode) {
        [self.popoverController dismissPopoverAnimated:self.animated];
    }
}

@end
The place where it's used in a view controller:
Code:
#pragma mark - UIStoryboard handlers
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"ConfigButton"]) {
        UINavigationController *navController = segue.destinationViewController;
        
        LAVSettingsController *vc = [navController.viewControllers objectAtIndex:0];
        
        SinglePopoverSegue *popoverSegue = (SinglePopoverSegue *)segue;
        
        if (!__popoverController) {
            __popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverSegue.destinationViewController];
        }
        popoverSegue.barButtonItem = sender;
        popoverSegue.popoverController = self.popoverController;
        vc.popoverController = self.popoverController;
        
        [self.popoverController setContentViewController:navController];
    }
}
So you can see from the code in prepareForSegue: that I can't get enough information into the segue in IB, so I have to do it here. In particular, I can't get (or find) the "source" element, the place from which the popover originates, which is an important aspect of a UIPopoverController.

EDIT: it's not entirely obvious that __popoverController is the backing store for the popoverController property. It's got 2 underscores because UIViewController already has a property called _popoverController but I can't actually get access to that to store MY popover controller. This is probably a risky use of the name, but whatever. If it becomes a problem, I'll deal with it then.
 
Last edited:

dejo

Moderator
Staff member
Sep 2, 2004
15,981
450
The Centennial State
EDIT: it's not entirely obvious that __popoverController is the backing store for the popoverController property. It's got 2 underscores because UIViewController already has a property called _popoverController but I can't actually get access to that to store MY popover controller. This is probably a risky use of the name, but whatever. If it becomes a problem, I'll deal with it then.
Maybe you could call it _myPopoverController. :)
 

Similar threads

Register on MacRumors! This sidebar will go away, and you'll see fewer ads.