如何将 UI 元素保留在 UIViewController 及其呈现的 ViewController 之上?

Posted

技术标签:

【中文标题】如何将 UI 元素保留在 UIViewController 及其呈现的 ViewController 之上?【英文标题】:How do I keep UI elements above a UIViewController and its presented ViewController? 【发布时间】:2017-10-23 15:25:29 【问题描述】:

我想在我的应用的第一个 VC 之上以及它呈现的第二个 VC 之上显示一些 UI 元素,例如搜索栏。

我的解决方案是创建一个 ContainerViewController,它调用 addChildViewController(firstViewController)view.addSubview(firstViewController.view)。然后是view.addSubview(searchBarView),每个 UI 元素都类似。

稍后,FirstViewController 可能会调用present(secondViewController),理想情况下,它会向上滑动到屏幕上,而我的搜索栏和其他元素仍会出现在两个视图控制器的顶部。

相反,secondViewController 显示在 ContainerViewController 之上,从而隐藏了搜索栏。

我还希望,当用户点击搜索栏时,ContainerViewController 会在所有内容之上显示 SearchVC。为此,它很简单 - containerVC.present(searchVC)

我怎样才能让这个层次结构正常工作?

【问题讨论】:

使用 containerviewcontroller 看起来不错。只是当你想展示第二个控制器时,你可以使用自定义视图动画或基于导航的转换来转换 secondVC,就像你使用 present(secondViewController) 一样。这样最顶部的 UI 元素将不会隐藏。 【参考方案1】:

如果我理解正确,您的问题是如何在子视图控制器的顶部(和边界内)呈现视图控制器,该子视图控制器的框架可能与父视图的边界不同。这可以通过将您要呈现的视图控制器的modalPresentationStyle 属性设置为.overCurrentContext 并将您的子视图控制器的definesPresentationContext 设置为true 来实现。

下面是一个简单的例子,展示了它在实践中是如何工作的:

override func viewDidLoad() 
    super.viewDidLoad()

    let childViewController = UIViewController()
    childViewController.view.backgroundColor = .yellow
    childViewController.view.translatesAutoresizingMaskIntoConstraints = true
    childViewController.view.frame = view.bounds.insetBy(dx: 60, dy: 60)
    view.addSubview(childViewController.view)
    addChildViewController(childViewController)
    childViewController.didMove(toParentViewController: self)

    // Wait a bit...
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) 
        let viewControllerToPresent = UIViewController()
        viewControllerToPresent.modalPresentationStyle = .overCurrentContext // sets to show itself over current context
        viewControllerToPresent.view.backgroundColor = .red

        childViewController.definesPresentationContext = true // defines itself as current context
        childViewController.present(viewControllerToPresent, animated: true, completion: nil)
    

【讨论】:

以上是关于如何将 UI 元素保留在 UIViewController 及其呈现的 ViewController 之上?的主要内容,如果未能解决你的问题,请参考以下文章

不要在 Vue、TailwindUI 和 Headless UI 中使用内置或保留的 HTML 元素

如何向 Material-UI 的 AppBar 组件添加多个元素?

UI-Router:如何在切换视图时保留视图

如何调整克隆的 jQuery UI 元素的大小(图片)

具有两列和三个卡片 ui 元素的相同高度

jQuery UI:从原始 div 拖动和克隆,但保留克隆