iOS 在弹出窗口中显示视图控制器

Posted

技术标签:

【中文标题】iOS 在弹出窗口中显示视图控制器【英文标题】:iOS Present View Controller Within Popup 【发布时间】:2017-10-13 16:01:15 【问题描述】:

所以我有我的主视图控制器。该视图控制器有一个带有情节提要 segue 的条形按钮项,其种类设置为 Present As Popover。

这一切都按预期工作。但是,当您点击该弹出视图控制器中的另一个按钮时,它会显示全屏视图。我希望它显示在弹出框内。就像在现有的弹出框边界上推送/显示一样。

我怎样才能做到这一点?

我只希望 iPad 上有这种行为。但我认为默认情况下它会这样做。

编辑

我更愿意在情节提要中完成这一切,但如果需要,我也愿意使用 Swift 代码来完成。

【问题讨论】:

你试过了吗? github.com/lkzhao/Hero @elk_cloner 这看起来像一个动画库。不是我要找的。​​span> 这个第三方可以帮助你:github.com/huynguyencong/EzPopup 【参考方案1】:

为您的UIBarButtonItem 创建一个IBAction,并在行动中:

- (IBAction)popupAction:(UIBarButtonItem *)sender 
    UIViewController *vc = [[UIViewController alloc] init];  // I don't use segue
    vc.view.backgroundColor = [UIColor grayColor];
    vc.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popvc = vc.popoverPresentationController;
    popvc.delegate = self;
    popvc.permittedArrowDirections = UIPopoverArrowDirectionAny;
    popvc.barButtonItem = sender; // if UIBarButtonItem
    // if view
    // popvc.sourceView = sender;
    // popvc.sourceRect = sender.bounds;

    vc.preferredContentSize = CGSizeMake(200, 200);

    [self presentViewController:vc animated:YES completion:nil];

还有UIPopoverPresentationControllerDelegate

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection
    return UIModalPresentationNone;


- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController
    return YES;

斯威夫特:

@IBAction func popupAction(_ sender: UIBarButtonItem) 
    let vc = UIViewController.init()
    vc.view.backgroundColor = UIColor.gray
    vc.modalPresentationStyle = UIModalPresentationStyle.popover
    let popvc = vc.popoverPresentationController
    popvc?.delegate = self
    popvc?.permittedArrowDirections = UIPopoverArrowDirection.any
    popvc?.barButtonItem = sender
    vc.preferredContentSize = CGSize.init(width: 200, height: 200)

    self.present(vc, animated: true, completion: nil)


func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle 
    return UIModalPresentationStyle.none


func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool 
    return true

这适用于 iPad 和 iPhone。

结果:

在 popover 控制器中弹出另一个 viewController:

【讨论】:

我正在使用 Swift 同样的问题。 UIBarButtonItem 将视图控制器显示为弹出框,但是当您单击弹出框内的按钮时,它不会显示在弹出框内,而是全屏显示。 你的意思是在popover vc里面popover另一个vc? 是的。所以UIBarButtonItem 会显示一个弹出框。在那个视图控制器/弹出框里面我有按钮。我希望这些按钮在原始弹出框内显示视图控制器,而不是作为全屏视图控制器。而且我宁愿只使用情节提要来实现这一点,而不是使用代码。但是,如果我必须使用也可以的代码。使用情节提要更加简洁。 如果不是UIBarButtonItem ,则需要使用sourceViewsourceRect。我添加了另一个视图控制器的弹出图像。【参考方案2】:

这仅适用于情节提要。

1) 创建一个 UIViewController(蓝色)并 ctrl + 拖动(鼠标)从您的 UIBarButtonItem 到 UIViewController 并选择“呈现为 Popover”(就像您所做的那样)。

2) 点击 UIViewController(蓝色)并点击 Editor->embed in->Navigation Controller(这将是让下一个控制器留在弹出窗口中的技巧)

3) 创建第二个 UIViewController(绿色)

4) 在第一个 UIViewController(蓝色)中创建一个 UIButton,然后 ctrl + 从按钮拖动到第二个 UIViewController(绿色)并选择“显示”

最后它在 Storyboard 中应该是这样的:

结果:

如果你想要没有导航栏的 PopOver,你可以在蓝色控制器中使用:

self.navigationController?.isNavigationBarHidden = true

并从绿色返回到蓝色视图,您可以在绿色控制器中使用:

@IBAction func backToBlueController(sender: UIButton) 
        self.navigationController?.popViewController(animated: true)

补充:

如果您不想使用 popUp,您也可以将 segue 类型从 barButtonItem 更改为 navigationController 到

模态呈现

和类似的演示文稿

表格

在故事板中。

一目了然,您应该始终使用 UINavigationController 来管理您的导航,即使您不需要导航栏,因为导航控制器为您提供了一个导航堆栈,您可以从中弹出和推入它。

UINavigationController Reference

【讨论】:

谢谢!无论如何要删除顶部的导航栏?它真的不适合我的设计。稍后我可能会重新设计以使其适合应用程序样式,但不是现在。同样在bluegreen 视图中,我有一个运行dismiss(animated: false, completion: nil) 的按钮。无论如何,blue 视图上是否有关闭整个弹出框的方法,以及green 视图上是否返回blue 视图?我知道这可能可以通过导航栏修复,但它不适合应用程序样式。另外,在 iPhone 上,导航栏在 blue 视图上没有关闭按钮。 self.navigationController.navigationBarHidden = true 将删除导航栏。 (在蓝色控制器中)和绿色控制器中的 self.navigationController.popViewControllerAnimated(true) 会将绿色弹回蓝色 对不起,在我的国家现在是晚上 11 点,我只能在星期一看看如何关闭 popOver,但这绝对是可能的。 关闭我可以用dismiss 做的弹出框。我想我的最后一个问题是green 视图可以在没有导航控制器和弹出框的情况下显示。我可以做类似if self.navigationController? 之类的事情并把self.navigationController.popViewControllerAnimated(true) 放在那里,然后在else 语句中放dismiss(animated: false, completion: nil) 吗?如果没有 navigationController 并且它是从另一个没有 navigationController 或 popover 的部分显示的,那会恢复到 dismiss 吗? 我认为你可以在蓝色上使用 self.dismissViewControllerAnimated(true) 来关闭整个 popOver【参考方案3】:

你试过了吗 - EzPopup (https://github.com/huynguyencong/EzPopup),一个 Swift pod。几行代码:

// init YourViewController
let contentVC = ...

// Init popup view controller with content is your content view controller
let popupVC = PopupViewController(contentController: contentVC, popupWidth: 100, popupHeight: 200)

// show it by call present(_ , animated:) method from a current UIViewController
present(popupVC, animated: true)

【讨论】:

以上是关于iOS 在弹出窗口中显示视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

在弹出窗口中呈现模态视图

表视图控制器在弹出窗口中分配给 contentViewController 属性时不显示数据

在弹出窗口中显示多个图像

在哪里设置弹出窗口中显示的视图控制器的大小?

UITableViewController 在弹出窗口中显示不同,为啥?

将视图控制器显示为弹出窗口-iOS8