自适应弹出窗口上的关闭按钮
在故事板中,我有一个带有按钮的根视图控制器,该按钮触发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;
}