Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

creating button for popover view anchor at run time

This may not be possible, but I'm hoping someone will have an idea how to do it.

I have an app I'm porting from iPhone only to Universal. On the iPhone, I'm using a Tabbed application. I use three tabs for the normal data to be displayed. I have a forth tab that's only displayed if certain conditions are met. To add the tab, I do:

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 
{
    UITabBarController *tabController = (UITabBarController *) self.rootViewController;
    NSMutableArray* newArray = [NSMutableArray arrayWithArray: tabController.viewControllers];
    [newArray addObject: [theStoryboard instantiateViewControllerWithIdentifier: @"AdditionalView-Phone"]];
    [tabController setViewControllers:newArray animated:YES];
}

For the iPad, I have enough space on the initial view to display everything from the main three tabs in the iPhone UI. So all I need is one additional (small) view for the "Additional" data. I wanted to do it using a popOver view, so I set up the initial view with a Nav bar and popover button as in the Utility App template. But now I'm stuck. I can't figure out how to create that popover button at run time and make it do the segue to the popOver view properly. I can add the button like this:

UIBarButtonItem *flipButton = [[UIBarButtonItem alloc] initWithTitle: @"Modem" style: UIBarButtonItemStylePlain target: self action: @selector(togglePopover:)];
self.navBar.topItem.rightBarButtonItem = flipButton;

but I get an exception: 'NSInternalInconsistencyException', reason: 'UIStoryboardPopoverSegue must be presented from a bar button item or a view.' I'm pretty sure this is because I don't have an anchor set for the popOver segue. The button doesn't exist in the storyboard, so I can't set it there. And I can't seem to find an API to set it at run time.

I also tried creating the button in IB, but not in the view hierarchy, and then just setting the rightBarButtonItem property to my existing button. That also works, but I still can't set that button as the anchor for the popover view. I can set the Navigation Bar as the anchor, but that makes it anchor to the title in the nav bar, which looks silly.

Any ideas?

like image 508
Flyingdiver Avatar asked Oct 16 '11 20:10

Flyingdiver


4 Answers

I had the same problem and solved it by creating a UIBarButtonItem in the Storyboard for the view controller but not part of the view hierarchy.

In IB, Drag a bar button item to the dark bar below the view controller view, drop it next to the "First Responder" and "View Controller" icons. Create a (strong) IBOutlet for it. Then create a popover segue from it to the destination view controller by dragging from the bar button item to the destination. It seems like this is the only way to set it as the anchor. Choosing it as the anchor for an existing segue does not work (looks like an IB bug).

enter image description here

In viewDidLoad you can assign this bar button item to the navigationItem (or where ever you like) and the segue works as expected.

like image 170
Chris Miles Avatar answered Nov 06 '22 11:11

Chris Miles


I was curious about this too so I made a quick test project. You're right, there doesn't seem to be a way to configure the popover segue at runtime or add an anchor point to a button that's not in the view hierarchy using Interface Builder.

My solution was to set everything up in IB with the UIBarButtonItem visible and connected to an IBOutlet property, then remove it from the navigation bar in -viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.navigationItem.rightBarButtonItem = nil;
}

Then I simply add it back or remove it by tapping another button:

- (IBAction)toggleBarButtonItem:(id)sender
{
    UIBarButtonItem *item = (self.navigationItem.rightBarButtonItem == nil) ?  self.popoverBarButtonItem : nil;
    [self.navigationItem setRightBarButtonItem:item animated:YES];
}

You could conditionally keep or remove the button in -viewDidLoad the same way. The segue remains anchored to the UIBarButtonItem.

like image 42
Ryder Mackay Avatar answered Nov 06 '22 13:11

Ryder Mackay


I'm gonna try making a dummy view that's the size and shape of the views I want to present the popover from, wire that to the segue popover target, and then move the view to the right position in prepareForSegue:sender:

like image 44
Michael Forrest Avatar answered Nov 06 '22 12:11

Michael Forrest


I'm not sure this is exactly what you want, but this is what I would do. Create a button and set it up with some target/action. Call that target/action method

presentPopover:(UIButton *)sender;

Then in the presentPopover method, say

UIViewController *customAdditionalViewController = [[MySpecialVC alloc] init];
//Configure the customAdditionalViewController
//Present the customAdditionalViewController in a Popover
UIPopoverController *popover = [[UIPopoverController alloc] initWithViewController:customAdditionalViewController];
//Set popover configurations
[popover presentPopoverFromRect:sender.frame inView:self.view permittedArrowDirections:/*whatever you want*/ animated:YES];

That is how I would handle your use case.

like image 22
Sloane Sturzenegger Avatar answered Nov 06 '22 13:11

Sloane Sturzenegger