在故事板中,我有一个带有按钮的根视图控制器,该按钮触发“弹出”按钮。 segue到包含UITableViewController的UINavigationController。我希望导航控制器出现在iPhone和iPad上。
在iPad上,这在popover中效果很好。
在iPhone上,我得到了模态演示,所以现在我需要一个额外的条形按钮项来消除模态视图。通过观看WWDC视频,我在根视图控制器中尝试了以下内容:
- (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上作为模态运行也是如此。
答案 0 :(得分:13)
对于那些想要快速剪切和粘贴的人来说,这是尼克斯的正确答案的Swift版本。
注意:这是在iPad上创建一个弹出框,但是在iPhone上有一个关闭按钮的模态表。
在Xcode 6.3故事板中,您连接了一个视图控制器并将segue指定为“作为弹出窗口存在”
下面的代码应该放在视图控制器中,该控制器会切换到popover,而不是popover本身:
首先设置popover委托:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "myPopoverSegueName" {
segue.destination.popoverPresentationController?.delegate = self
return
}
}
然后添加委托扩展并动态创建导航控制器/关闭按钮:
extension myViewController: UIPopoverPresentationControllerDelegate {
func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
let btnDone = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.dismissPopover))
let nav = UINavigationController(rootViewController: controller.presentedViewController)
nav.topViewController?.navigationItem.leftBarButtonItem = btnDone
return nav
}
@objc private func dismissPopover() {
dismiss(animated: true, completion: nil)
}
}
答案 1 :(得分:12)
好的,我已经成功实现了它。我认为我的问题是popoverPresentationController
属性遍历视图控制器层次结构,直到它找到一个带有popoverPresentationController
的视图控制器,即如果我在视图控制器内部的导航控制器内有一个视图控制器popoverPresentationController
将转到导航控制器并使用它的属性。为此,视图控制器必须是导航控制器的子级。在我尝试使用popoverPresentationController
的所有要点中,情况并非如此,例如init
,viewDidLoad
,viewWillAppear
。出于某种原因,即使willMoveToParentViewController
被调用,也不会调用didMove
。所以我不知道如何在调用ppc委托方法之前在导航控制器中的vc中引用popoverPresentationController
。
但是,您可以在prepareForSegue
中的呈现视图控制器中引用它,但您需要明确告诉它要使用的演示样式。这是我放置在呈现视图控制器中的代码:
- (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;
}
答案 2 :(得分:0)
我发现the accepted answer在紧凑模式下(例如iPhone)没有正确显示“完成”按钮,但在普通模式(例如iPad)中保持弹出状态。
以下代码是实现此功能的最低要求 - 将它们放在呈现视图控制器类中。
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIViewController *dest = segue.destinationViewController;
dest.popoverPresentationController.delegate = self;
}
- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style {
UIViewController* presentedViewController = controller.presentedViewController;
if ([controller isKindOfClass:[UIPopoverPresentationController class]] && style == UIModalPresentationFullScreen) {
UINavigationController* navCtrl = [[UINavigationController alloc] initWithRootViewController:presentedViewController];
UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(dismiss:)];
presentedViewController.navigationItem.rightBarButtonItem = bbi;
return navCtrl;
}
return presentedViewController;
}
-(IBAction)dismiss:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
注意与接受答案的三个不同之处:
adaptivePresentationStyleForPresentationController: