在运行时为弹出窗口视图锚点创建按钮

时间:2011-10-16 20:33:00

标签: ios ipad uinavigationbar uipopovercontroller

这可能是不可能的,但我希望有人知道该怎么做。

我有一个应用程序,我只从iPhone移植到环球影城。在iPhone上,我使用的是Tabbed应用程序。我使用三个选项卡显示正常数据。我有一个第四个标签,只有在满足某些条件时才会显示。要添加标签,我会这样做:

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];
}

对于iPad,我在初始视图上有足够的空间来显示iPhone UI中主要三个选项卡的所有内容。所以我需要的是“附加”数据的另一个(小)视图。我想使用popOver视图来完成它,所以我使用Nav bar和popover按钮设置初始视图,就像在Utility App模板中一样。但是现在我被卡住了。我无法弄清楚如何在运行时创建弹出窗口按钮并使其正确执行popOver视图。我可以像这样添加按钮:

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

但我得到一个例外:'NSInternalInconsistencyException',原因:'UIStoryboardPopoverSegue必须从条形按钮项或视图中显示。'我很确定这是因为我没有为popOver segue设置锚点。故事板中不存在该按钮,因此我无法将其设置在那里。我似乎无法在运行时找到一个API来设置它。

我也尝试在IB中创建按钮,但不在视图层次结构中创建按钮,然后只将rightBarButtonItem属性设置为现有按钮。这也有效,但我仍然无法将该按钮设置为弹出视图的锚点。我可以将导航栏设置为锚点,但这会使它锚定到导航栏中的标题,这看起来很傻。

有什么想法吗?

4 个答案:

答案 0 :(得分:13)

我遇到了同样的问题并通过在视图控制器的Storyboard中创建UIBarButtonItem但不是视图层次结构的一部分来解决它。

在IB中,将条形按钮项拖动到视图控制器视图下方的暗条,将其放在“第一响应者”和“视图控制器”图标旁边。为它创建一个(强大的)IBOutlet。然后通过从条形按钮项拖动到目标,从它创建一个popover segue到目标视图控制器。看起来这是将它设置为锚点的唯一方法。选择它作为现有segue的锚点不起作用(看起来像IB错误)。

enter image description here

在viewDidLoad中,您可以将此栏按钮项指定给navigationItem(或您喜欢的任何位置),并且segue按预期工作。

答案 1 :(得分:3)

我对此也很好奇所以我做了一个快速测试项目。你是对的,似乎没有办法在运行时配置popover segue或者使用Interface Builder将锚点添加到不在视图层次结构中的按钮。

我的解决方案是在IB中设置所有内容,UIBarButtonItem可见,并连接到IBOutlet属性,然后将其从-viewDidLoad的导航栏中删除:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.navigationItem.rightBarButtonItem = nil;
}

然后我只需将其添加回来或通过点击另一个按钮将其删除:

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

您可以以同样的方式有条件地保留或删除-viewDidLoad中的按钮。 segue仍然固定在UIBarButtonItem

答案 2 :(得分:3)

我要尝试制作一个虚拟视图,它是我想要显示弹出窗口的视图的大小和形状,将其连接到segue popover目标,然后将视图移动到{{1}中的正确位置}

答案 3 :(得分:2)

我不确定这正是你想要的,但这就是我要做的。创建一个按钮并使用一些目标/操作进行设置。称之为目标/行动方法

presentPopover:(UIButton *)sender;

然后在nowPopover方法中,说

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];

这就是我处理你的用例的方法。