Ios 在运行时为popover视图锚创建按钮

Ios 在运行时为popover视图锚创建按钮,ios,ipad,uinavigationbar,uipopovercontroller,Ios,Ipad,Uinavigationbar,Uipopovercontroller,这可能是不可能的,但我希望有人能想出办法 我有一个只从iPhone移植到Universal的应用程序。在iPhone上,我使用的是一个选项卡式应用程序。我使用三个选项卡来显示正常数据。我有一个第四个选项卡,只有在满足某些条件时才会显示。要添加选项卡,我需要执行以下操作: if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { UITabBarController *tabCont

这可能是不可能的,但我希望有人能想出办法

我有一个只从iPhone移植到Universal的应用程序。在iPhone上,我使用的是一个选项卡式应用程序。我使用三个选项卡来显示正常数据。我有一个第四个选项卡,只有在满足某些条件时才会显示。要添加选项卡,我需要执行以下操作:

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,我在初始视图上有足够的空间来显示iphoneui中主要三个选项卡的所有内容。所以我只需要一个额外的(小)视图来显示“额外”数据。我想使用popOver视图来实现这一点,所以我使用导航栏和popOver按钮设置了初始视图,就像在实用程序应用程序模板中一样。但现在我被卡住了。我不知道如何在运行时创建popover按钮,并使其正确地切换到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中创建按钮,但没有在视图层次结构中创建,然后将RightBarButtonim属性设置为我现有的按钮。这同样有效,但我仍然无法将该按钮设置为popover视图的锚定。我可以将导航栏设置为锚定,但这会使它锚定到导航栏中的标题,这看起来很愚蠢


有什么想法吗?

我对此也很好奇,所以我做了一个快速测试项目。没错,似乎没有办法在运行时配置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仍然锚定在
uibarbuttonite上

我不确定这正是您想要的,但这是我要做的。创建一个按钮并设置一些目标/操作。调用该目标/操作方法

presentPopover:(UIButton *)sender;
然后在presentPopover方法中

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

这就是我将如何处理您的用例。

我将尝试创建一个虚拟视图,该视图的大小和形状是我要从中呈现popover的视图,将其连接到segue popover目标,然后将视图移动到
prepareforsgue:sender:

中的正确位置。我遇到了同样的问题,通过在脚本中为视图控制器创建UIBarButtonim来解决,但不是视图层次结构的一部分

在IB中,将一个条形按钮项拖动到视图控制器视图下方的黑色条形图上,将其放置在“First Responder”和“view controller”图标旁边。为它创建一个(强大的)IBOutlet。然后通过从工具栏按钮项拖动到目标,创建一个从它到目标视图控制器的popover segue。看来这是唯一能让它成为锚的方法。选择它作为现有segue的锚不起作用(看起来像IB bug)


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

Hey@Flyingdiver您找到解决方案了吗?是的,制作一个隐藏的UIView,从中显示弹出框,并将其移动到您需要的任何位置。它工作正常!隐藏虚拟视图似乎也不会导致问题。