我是iOS开发的新手,我正在尝试同时学习故事板,Swift和iOS 8的新功能。
我创建了一个非常简单的故事板,它使用Popover演示文件segue来显示另一个视图。在模拟器上,如果我为iPad运行它,它按预期工作。但是,如果我为iPhone而不是弹出窗口运行它,它会在原始视图的顶部显示全屏视图。这可以;但是,没有办法解雇它并回到原来的屏幕。
我观看了WWDC 2014视频“228 A Look inside presentation controllers”,如果他们完全使用代码构建用户界面,他们可以显示一个关闭按钮。
我还看过“411界面构建器中的新功能”会话,他们说这可以在Interface Builder中完成,但他们没有显示它,承诺在实验室中展示如何做到这一点,如果有人有兴趣。不幸的是,我没有参加WWDC 2014,或者认识任何人。我的Google搜索也没有返回任何有用的内容。
答案 0 :(得分:12)
您可以像这样添加导航控制器 -
如果你真的希望你的视图控制器永远是一个弹出窗口,请按原样保留你的故事板,并将这样的内容添加到你的视图控制器中,以显示popover-
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"Your segue name"]) {
UIViewController *yourViewController = segue.destinationViewController;
yourViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popoverPresentationController = yourViewController.popoverPresentationController;
popoverPresentationController.delegate = self;
}
}
呈现弹出窗口的视图控制器还需要响应此UIPopoverPresentationDelegate
方法
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;//always popover.
}
最后,您可以执行以下操作,仅将导航控制器添加到iPhone上视图控制器的模式演示文稿中,并将弹出窗口保留在iPad上,而不使用导航控制器。
注入导航控制器的正确位置在- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style
。为了调用它,我们必须将自己设置为UIPopoverPresentationController
的委托。
我们将再次在prepareForSegue:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"Your segue name"]) {
UIViewController *yourViewController = segue.destinationViewController;
yourViewController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popoverPresentationController = yourViewController.popoverPresentationController;
popoverPresentationController.delegate = self;
}
}
然后我们将在上面提到的委托方法中执行此操作
-(UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style
{
UIViewController *presentedViewController = controller.presentedViewController;
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:presentedViewController];
UIBarButtonItem *dismissButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonItemStyleDone target:self action:@selector(done:)];
presentedViewController.navigationItem.rightBarButtonItem = dismissButton;
return navigationController;
}
祝你好运!
答案 1 :(得分:10)
如果您想要的是iPad上的弹出窗口,但是iPhone上有关闭按钮的模态表,那么您可以在故事板中为弹出框创建额外的导航控制器。
在Xcode 6.3故事板中,您只需连接一个视图控制器并将segue指定为“作为弹出窗口存在”
下面的代码应该放在视图控制器中,该控制器会切换到popover,而不是popover本身:
首先设置popover委托:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "myPopoverSegueName") {
let vc = segue.destinationViewController
vc.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: "dismiss")
let nav = UINavigationController(rootViewController: controller.presentedViewController)
nav.topViewController.navigationItem.leftBarButtonItem = btnDone
return nav
}
}
然后你添加你的解雇功能,你应该好好去:
func dismiss() {
self.dismissViewControllerAnimated(true, completion: nil)
}
答案 2 :(得分:3)
我不确定为什么你需要为Done按钮设置故事板设置,所有的工作都可以通过几行代码以编程方式完成。重要的是实现一些UIAdaptivePresentationControllerDelegate
协议方法,如下所示:
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle
{
return .FullScreen
}
func presentationController(controller: UIPresentationController,
viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController?{
var navController:UINavigationController = UINavigationController(rootViewController: controller.presentedViewController)
controller.presentedViewController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action:"done")
return navController
}
然后,一个简单的方法来实现popover的解雇行为,以防全屏显示:
func done (){
presentedViewController?.dismissViewControllerAnimated(true, completion: nil)
}
你完成了!
答案 3 :(得分:1)
在我的情况下,我有一个小弹出窗口,我想在iPhone和iPad上弹出一个弹出窗口 - 并希望避免使用带有Dismiss的导航栏。发现需要实现两个委托调用(Swift 3.0):
extension MyViewController : UIPopoverPresentationControllerDelegate {
// Needed for iPhone popup
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
// Needed for iPhone in landscape
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
return .none
}
}
答案 4 :(得分:0)
使用mimimal代码可以实现它,同时将逻辑放入故事板。在呈现弹出框的视图控制器中,只需放入标记方法
@IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {
}
它不需要任何代码但需要存在,因此您可以在以后使用界面构建器时控制拖动到“退出”图标。
我的popover内容不占用整个背景视图,但周围的边距很小。这意味着您可以使用界面构建器为此视图创建轻击手势识别器。控制将手势识别器拖动到Exit图标,然后弹出一些Exit选项,其中一个是unwindToContainerVC方法,如上所示。
现在任何边缘的点击(例如在iPhone 4S场景中)都会将您带回到呈现视图控制器。