IOS AdaptiveView Popover和NavigationController:它们如何工作?

时间:2015-08-14 08:31:50

标签: ios adaptive-layout

我正在将旧的应用程序更新为新的自适应大小的处理方式,并且难以使用导航控制器来实现弹出窗口。

我的目标:当应用程序紧凑且常规水平时,我希望能够从按钮打开弹出窗口。 popover有一个tableview,当用户触摸桌面上的一行时,它使用导航控制器推送视图控制器。我可以正确打开popover,但我无法弄清楚推动工作的对象。

这是打开popover的代码:

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以使其工作。经过三四天的挖掘,试图了解如何使这项工作,我感谢任何见解,或链接到有关如何做到这一点的文档。提前谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

最后,我介绍了navigationController:

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

这种方法以紧凑和规则的水平尺寸呈现弹出窗口,其中包含导航控制器功能:正是我想要的。

再次感谢Larcerax,他的回答不是我需要的,但让我重新思考我以不同的方式做的事情。像往常一样,StackOverflow会通过。

答案 1 :(得分:0)

这是你应该尝试的。对于我工作的应用程序,我每个应用程序使用大约10-40个导航控制器,我有同样的问题,我没有使用弹出窗口,但我已经将导航控制器和视图控制器的废话子类化了遇到了同样的问题。问题是,如果你这样做:

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

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

请参阅以下内容,它不适用于弹出窗口,但原理是相同的:

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< ==是UIViewcontroller的另一个子类的子类,它基本上是类固醇上的UIViewController,全部是

NSHNavigationController是一个UINavigationController,它被子类化并用于动画的类固醇

流程是这样的:

  1. 创建一个viewController
  2. 创建一个新的UINavigationController
  3. 将您在步骤1中创建的视图控制器设置为在步骤2中创建的导航控制器的根视图控制器
  4. 介绍NAVIGATION CONTROLLER,而不是UIViewController,你可以从视图控制器中提供这个navigationController,就像这样..
  5. 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];
    

    这个:[[self contentView] nameField] .frame只是一个uitextfield,没有什么特别的,就是这一切,上面的方法提供了登录viewcontroller,当我输入我的凭据时,我按下了登录,然后它将puse下一个像往常一样,viewcontroller,你的uitableview或其他任何东西拦截的触摸都是错误的,也许不是,但这种方法对我有效。