【问题标题】:IOS AdaptiveView Popover and NavigationController: how do they work?IOS AdaptiveView Popover 和 NavigationController:它们是如何工作的?
【发布时间】:2015-08-14 08:31:50
【问题描述】:

我正在将一个旧应用程序更新为新的自适应大小的处理方式,并且很难让带有导航控制器的弹出框工作。

我的目标:当应用程序紧凑且常规水平时,我希望能够从按钮打开弹出框。弹出框有一个表格视图,并在用户触摸表格上的一行时使用导航控制器推送视图控制器。我可以让弹出框正确打开,但我不知道由谁来进行推送。

这是打开弹出框的代码:

OptionsController *vc = [[OptionsController alloc] initWithNibName:@"OptionsView" bundle:nil];
vc.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popover = [vc popoverPresentationController];
popover.delegate = self;
[self presentViewController:vc animated: YES completion: nil];

popover.permittedArrowDirections = UIPopoverArrowDirectionUp;  // change as necessary
popover.sourceView = self.view;
CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
popover.sourceRect = popoverRect;

此代码正确打开紧凑或常规大小的弹出框。

在OptionsController的didSelectRowAtIndexPath方法中,我有这个(controllersArray是UIViewControllers的数组,每个对应表中的一行):

    UIViewController *nextController = [self.controllersArray objectAtIndex: [indexPath row]];
    [self.navigationController pushViewController:nextController animated:YES];

这一切都执行了,但没有推送发生,所以下一个视图永远不会出现。

我显然不了解如何使用 UIViewController 的 navigationController,或者如何安装 navigationController 来完成这项工作。经过三四天的挖掘以尝试了解如何进行这项工作,我将不胜感激任何见解或有关如何执行此操作的文档的链接。提前致谢。

【问题讨论】:

  • 你想在哪里推送 vc.. 在你的主 vc 中打开 popover 或在 vc 本身上弹出。
  • 我想从弹出框推送视图控制器。
  • 引用的链接是在弹出框被实现为presentationControllers之前完成的。如果我按下导航控制器,我会得到一个模态全屏视图——这不是我想要的。我希望能够打开一个弹出框 - 作为演示控制器 - 其中有一个工作导航控制器。我还没有弄清楚如何在 iOS8/9 中做到这一点。

标签: ios adaptive-layout


【解决方案1】:

Crud - 这有一个非常简单的答案。只是让我以不同的方式思考并挖掘了 Larcerax 的 cmets。以下是如何使这项工作:

    OptionsController *vc = [[OptionsController alloc] initWithStyle:UITableViewStylePlain];
    vc.title = @"Options";
    UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController: vc];
    nc.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popover = [nc popoverPresentationController];
    popover.delegate = self;
    [self presentViewController:nc animated: YES completion: nil];

    popover.permittedArrowDirections = UIPopoverArrowDirectionUp;  // change as necessary
    popover.sourceView = self.view;
    CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
    popover.sourceRect = popoverRect;

不同的是我以通常的方式创建 UINavigationController...

        UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController: vc]; 

...将navigationController 的显示样式设置为popover,然后从navigationController 中获取popoverPresentationController - 在我对UIViewController 执行这两个方法之前。

    nc.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popover = [nc popoverPresentationController];

最后,我介绍一下导航控制器:

    nc.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popover = [nc popoverPresentationController];

这种方法提供了一个弹出框,它具有紧凑且常规的水平尺寸,其中包含导航控制器功能:正是我想要的。

再次感谢 Larcerax,他的回答不是我所需要的,而是让我以不同的方式重新思考我在做什么。像往常一样,StackOverflow 出现了。

【讨论】:

    【解决方案2】:

    这是您应该尝试的。对于我正在使用的应用程序,我每个应用程序使用大约 10-40 个导航控制器,我也遇到过同样的问题,我没有使用弹出框,但我已经将导航控制器和视图控制器的垃圾分类为有遇到你同样的问题。问题是,如果你这样做:

     UIViewController * ff = [UIViewController new]
     [self presnetViewController:ff  ... blah blah blah
    

    模态视图控制器显然没有附加导航系统,因此您无法导航到其他任何内容,您只能关闭模态并继续前进。所以,这就是我要解决的问题,它每次都有效,它每次都适用于 UIViewControllers,试一试

    看下面,不是popovers,但原理是一样的:

    NSHTermsOfServiceViewController * pvc = [NSHTermsOfServiceViewController new];
    UIBarButtonItem * backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"exit-button"] style:UIBarButtonItemStylePlain target:self action:@selector(backerPressed)];
    NSHNavigationController * ssf = [[NSHNavigationController alloc] initWithRootViewController:pvc];
    [[pvc navigationItem] setLeftBarButtonItem:backBarButtonItem];
    [[self navigationController] presentViewController:ssf animated:true completion:nil];
    

    NSHTermsOfServiceViewController

    NSHNavigationController 是一个 UINavigationController 的子类,并为动画注入了类固醇

    流程是这样的:

    1. 创建一个视图控制器
    2. 创建一个新的 UINavigationController
    3. 将您在步骤 1 中创建的视图控制器设置为在步骤 2 中创建的导航控制器的根视图控制器
    4. 呈现 NAVIGATION CONTROLLER,而不是 UIViewController,您可以像这样从视图控制器呈现这个 navigationController ..

    v

    [self presentViewController:ssf animated:true completion:nil];
    

    或者您可以从当前视图控制器的导航控制器中呈现它,这是我更喜欢的,如下所示:

    [[self navigationController] presentViewController:ssf animated:true completion:nil];
    

    您的代码已修改,唯一的问题是我不知道您是否可以通过将 UIPopOverViewController 植根于导航控制器中来呈现它

    OptionsController *vc = [[OptionsController alloc] initWithNibName:@"OptionsView" bundle:nil];
    
    UIPopoverPresentationController *popover = [vc popoverPresentationController];
    
    
    UINavigationController * stuff = [[NSHNavigationController alloc] initWithRootViewController:popover];
    stuff.modalPresentationStyle = UIModalPresentationPopover;
    stuff.delegate = self;
    
    [self.navigationController presentViewController:stuff animated: YES completion: nil];
    
    popover.permittedArrowDirections = UIPopoverArrowDirectionUp;  // change as necessary
    popover.sourceView = self.view;
    CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
    popover.sourceRect = popoverRect;
    

    是的,我的错,对popover不起作用,我刚刚尝试过

    那么,话虽如此,使用弹出框是绝对必要的吗?你为什么要使用它,而现在只是一个 UIViewcontroller,你重新配置它看起来像一个弹出框,然后你就拥有了你需要的东西?

    这是这个,我刚刚用 Ipad 模拟器试了一下,它允许推送,就像它应该有的那样。

    NSHLoginViewController * pvc = [NSHLoginViewController new];
    
    UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:pvc];
    UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController];
    
    UIView * stuff = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 1000, 1000)];
    [self.view addSubview:stuff];
    [popover presentPopoverFromRect:[[self contentView] nameField].frame inView:stuff permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
    

    this: [[self contentView] nameField].frame 只是一个 uitextfield,没什么特别的,仅此而已,上面的方法显示了登录视图控制器,当我输入我的凭据时,我按下了登录,它又按下了viewcontroller 正常情况下,您的 uitableview 或其他任何东西截获的触摸可能有问题,也许不是,但这种方法确实对我有用。

    【讨论】:

    • 非常感谢您的详细解释。在我看来,如果我展示导航控制器,我会得到一个模态视图,而不是弹出框,这是我真正想要的。我会尝试一下你的建议,看看我是否可以将这些原则应用于弹出窗口。再次感谢您的帮助。
    • 阅读我上面的其余答案,不确定它是否会对您有所帮助,但我确实让它从弹出窗口中将另一个视图控制器推送到堆栈上,只需按照相反的方式进行我给你看,把导航控制器作为弹出框的内容,这一切都说得通,那么这将使弹出框中的viewcontroller具有导航的能力
    • 我看到这个解决方案的一个问题是它使用了 presentPoverFromRect: 这是一种旧的、已弃用的显示弹出框的方法。我真的很想使用新的方式,将popover作为presentationController,使用presentViewController的presentationController方法呈现。不过,如果它有效,我可能会继续使用它。
    • 是的,这点不错,我去试试别的方法,看看能做什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-02
    • 2011-01-05
    • 1970-01-01
    • 2015-02-11
    • 2014-09-08
    相关资源
    最近更新 更多