【问题标题】:creating button for popover view anchor at run time在运行时为弹出视图锚创建按钮
【发布时间】:2011-12-08 21:11:55
【问题描述】:

这可能是不可能的,但我希望有人知道如何做到这一点。

我有一个应用程序,我只从 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,我在初始视图上有足够的空间来显示 iPhone UI 中三个主要选项卡中的所有内容。所以我只需要一个额外的(小)“附加”数据视图。我想使用 popOver 视图来实现,所以我使用导航栏和弹出按钮设置初始视图,就像在 Utility App 模板中一样。但现在我被困住了。我不知道如何在运行时创建该弹出按钮并使其正确地对 popOver 视图进行 segue。我可以像这样添加按钮:

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 属性设置为我现有的按钮。这也有效,但我仍然无法将该按钮设置为弹出视图的锚点。我可以将导航栏设置为锚点,但这会使其锚定到导航栏中的标题,这看起来很傻。

有什么想法吗?

【问题讨论】:

  • 嘿@Flyingdiver 你找到解决办法了吗?
  • 是的,制作一个隐藏的 UIView 以显示弹出框并将其移动到您需要的任何位置。

标签: ios ipad uinavigationbar uipopovercontroller


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    我将尝试制作一个虚拟视图,该视图的大小和形状是我想要从中呈现弹出框的视图,将其连接到 segue 弹出框目标,然后将视图移动到 prepareForSegue:sender: 中的正确位置/p>

    【讨论】:

    • 有效!隐藏虚拟视图似乎也不会导致问题。
    【解决方案3】:

    我不确定这是否正是您想要的,但这是我会做的。创建一个按钮并使用一些目标/操作对其进行设置。调用那个目标/动作方法

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

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

    【讨论】:

      【解决方案4】:

      我也对此很好奇,所以我做了一个快速测试项目。你是对的,似乎没有办法在运行时配置 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 中的按钮。转场仍然锚定在UIBarButtonItem

      【讨论】:

        猜你喜欢
        • 2017-12-26
        • 2020-11-16
        • 1970-01-01
        • 2022-10-01
        • 2014-03-09
        • 2010-12-23
        • 1970-01-01
        • 2011-12-13
        • 1970-01-01
        相关资源
        最近更新 更多