自适应弹出窗口上的关闭按钮

自适应弹出窗口上的关闭按钮

问题描述:

在故事板中,我有一个带有按钮的根视图控制器,该按钮触发Present as Popoversegue到包含UITableViewController的UINavigationController。我希望导航控制器能够出现在iPhone和iPad上。

In a storyboard I have a root view controller with a button which triggers a 'Present as Popover' segue to a UINavigationController containing a UITableViewController. I want the nav controller to be present on both iPhone and iPad.

在iPad上,这在popover中非常有效。

On an iPad, this works great in a popover.

在iPhone上,我得到了模态演示,所以现在我需要一个额外的条形按钮项来消除模态视图。从观看WWDC视频开始,我在根视图控制器中尝试了以下内容:

On an iPhone, I get the modal presentation, so now I need an additional bar button item to dismiss the modal view. From watching the WWDC videos, I've attempted the following in the root view controller:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    UIViewController *vc = segue.destinationViewController;
    vc.popoverPresentationController.delegate = self;
}

- (void)dismissPopover {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style {
    UINavigationController *nvc = (UINavigationController *)controller.presentedViewController;
    UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(dismissPopover)];
    nvc.topViewController.navigationItem.leftBarButtonItem = bbi;
    return nvc;
}

我理解 -presentationController:viewControllerForAdaptivePresentationStyle:方法只应在UI自适应时调用,即模态,但它根本不会被调用,即使在iPhone上作为模态运行也是如此。

I understand the -presentationController:viewControllerForAdaptivePresentationStyle: method should only get called when the UI is adaptive i.e. modal, however it doesn't get called at all, even when running as a modal on iPhone.

好的,我已经成功实现了它。我认为我的问题是 popoverPresentationController 属性遍历视图控制器层次结构,直到它找到一个带有的视图控制器popoverPresentationController ,即如果我在弹出框内的导航控制器内有一个视图控制器,视图控制器 popoverPresentationController 将转到导航控制器并使用它的属性。为此,视图控制器必须是导航控制器的子级。在我尝试使用 popoverPresentationController 的所有要点中,情况并非如此,例如 init viewDidLoad viewWillAppear 。出于某种原因,即使 didMove 被调用,也不会调用 willMoveToParentViewController 。所以我不知道如何在调用ppc委托方法之前在导航控制器内的vc中引用 popoverPresentationController

Ok, I have managed to get it working. I think my problem was that the popoverPresentationController property traverses up the view controller heirarchy until it finds a view controller with a popoverPresentationController, i.e. if I have a view controller inside a navigation controller inside a popover the view controller popoverPresentationController would go to the nav controller and use it's property. For this to work, the view controller has to be a child of the navigation controller. At all the points I was trying to use the popoverPresentationController, this was not the case, e.g init, viewDidLoad, viewWillAppear. For some reason, willMoveToParentViewController is not called, even though didMove does get called. So I have no idea how to reference popoverPresentationController in a vc inside a nav controller before the ppc delegate methods are called.

但是,您可以在 prepareForSegue 中的呈现视图控制器中引用它,但您需要明确告诉它要使用的演示样式。这是放置在呈现视图控制器中的代码:

However, you can reference it in the presenting view controller in prepareForSegue, but you do need to explicitly tell it what presentation style to use. Here's my code that works when placed in the presenting view controller:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    UIViewController *dest = segue.destinationViewController;
    dest.popoverPresentationController.delegate = self;
}

- (void)dismiss {
    [self dismissViewControllerAnimated:YES completion:nil];
}


- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
    return UIModalPresentationFullScreen; // required, otherwise delegate method below is never called.
}

- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style {
    // If you don't want a nav controller when it's a popover, don't use one in the storyboard and instead return a nav controller here
    UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(dismiss)];
    UINavigationController *nc = (UINavigationController *)controller.presentedViewController;
    nc.topViewController.navigationItem.leftBarButtonItem = bbi;
    return controller.presentedViewController;
}