将一个 ViewController 部分呈现在另一个之上

Posted

技术标签:

【中文标题】将一个 ViewController 部分呈现在另一个之上【英文标题】:Presenting one ViewController over another partially 【发布时间】:2018-10-02 15:32:11 【问题描述】:

我有一个MapViewController,它基本上是一个MKMapView,并提供了一个带有自定义注释的地图。

现在我正在尝试从底部展示另一个 ViewController,其中包含用户将能够在其旅程中使用的其他过滤器。

但是我遇到了一个问题,当我将新的FilterMenuViewController 呈现为MapViewController 的孩子时,MapViewController 消失了。

这就是它的样子:

Initial state

Button to present new controller tapped

New controller presented but the MapViewController disappearing

负责交互的代码如下:

MapViewController变量声明:

var filterMenuVC = FilterMenuViewController()
var isFilterMenuOpened = false

MapViewController viewDidLoad():

    filterMenuVC = storyboard?.instantiateViewController(withIdentifier: "FilterMenuViewController") as! FilterMenuViewController

MapViewController showFilterMenu按钮操作:

@IBAction func showFilterMenu(_ sender: UIButton) 
    // Presents the filter menu
    if isFilterMenuOpened == true 
        isFilterMenuOpened = false
        filterMenuVC.willMove(toParentViewController: nil)
        filterMenuVC.view.removeFromSuperview()
        filterMenuVC.removeFromParentViewController()
     else if isFilterMenuOpened == false 
        isFilterMenuOpened = true
        self.addChildViewController(filterMenuVC)
        self.view.addSubview(filterMenuVC.view)
        filterMenuVC.didMove(toParentViewController: self)
    
 

【问题讨论】:

您是否 100% 确定 filterMenuVC 的背景清晰?您对 filterMenuVC 应用了哪些框架/约束? 是的,我 100% 确定即使 alpha 为 0 并且 viewController 上没有任何内容,初始 MapViewController 也会被释放。 【参考方案1】:

试试这个,视图从顶部和反向显示,这是图像:https://imgur.com/a/gzIGjEa

if isFilterMenuOpened
            if let searching = self.childViewControllers.first as? ViewController
                UIView.animate(withDuration: 0.7, animations: 
                    searching.view.frame = CGRect.init(x: 0,
                                                       y: self.view.frame.origin.y-308,
                                                       width: self.view.frame.size.width,
                                                       height: 308)
                , completion: (boos) in
                    searching.removeFromParentViewController()
                    searching.dismiss(animated: true, completion: nil)
                    self.isFilterMenuOpened = false
                )
            
        else
            let search = self.storyboard?.instantiateViewController(withIdentifier: "searchView") as! ViewController
            search.view.frame = CGRect.init(x: 0, y: self.view.frame.origin.y-308, width: self.view.frame.size.width, height: 308) //The View controller height same size of your view in storyboard
            search.delegateSearch = self
            self.addChildViewController(search)
            UIView.animate(withDuration: 0.5, animations: 
                search.view.frame = CGRect.init(x: 0, y: self.view.frame.origin.y, width: self.view.frame.size.width, height: 308)
            )
            self.view.addSubview(search.view)
            self.didMove(toParentViewController: search)
            isFilterMenuOpened = true
        

【讨论】:

【参考方案2】:

问题是我创建了一个从按钮到 ViewController 的 segue “显示”,这与将控制器添加到当前视图相冲突,而是将其推入其中,并且 MapViewController 被释放。

所以我刚刚从 sotryboard 中删除了 segue 并以编程方式添加了孩子,它现在就像魅力一样。

这是一个愚蠢的错误,但也许这会帮助遇到同样问题的人:)

【讨论】:

试试代码,想象一下,view的黑色部分是因为你尝试在全屏呈现,你需要调整高度,像这样:CGRect.init(x: 0, y : self.view.frame.origin.y-308, width: self.view.frame.size.width, height: 308) 如果起点是屏幕底部,则 CGRect 值更改:CGRect.init(x: 0,y:self.view.frame.size.height-"yourViewSize",width:self.view.frame.width,height:"yourviewSize") Helo 我已经解决了我刚刚删除故事板 segue 并以编程方式将控制器添加为子的问题。

以上是关于将一个 ViewController 部分呈现在另一个之上的主要内容,如果未能解决你的问题,请参考以下文章

swift3:如何将 xib 呈现给 viewcontroller

呈现小Modal VIewController Objective C

更改呈现的第一个 viewController(主界面)

轻松实现部分背景半透明的呈现效果

Rails 3在另一个控制器中呈现部分形式

将 ViewController 呈现为弹出框