在解除模态视图控制器的动画时访问presentViewController

时间:2017-01-25 20:28:10

标签: ios iphone swift uiviewcontroller

我在主视图控制器中有一个按钮,它以模态方式呈现另一个视图控制器。当模态vc向上滑动时,我制作了主视图控制器的自定义动画。但是,当modal vc向下滑动时(使用dismiss),如何让它向后移动? 使用this site 上的教程,我创建了访问呈现vc的协议,但动画不会发生,只是立即改变不透明度。

另外,如果我将动画代码放入呈现vc的viewWillAppear中,它只在模式vc一直向下滑动(消失)时才启动动画。我没有使用常规show segue,因为我不认为这是摆脱模态vc的最好方法。如果我错了,请纠正我

这是演示vc中的prepareForSegue

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let identifier = segue.identifier{
        switch identifier {
        case "showSettings":
            let tempFrame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
            dimView = UIView(frame: tempFrame)
            dimView.backgroundColor = .black
            dimView.layer.opacity = 0
            self.view.addSubview(dimView)
            UIView.animate(withDuration: 0.5, animations: {
                self.dimView.layer.opacity = 0.4
            })
        default:break
        }
    }
    if let vc = segue.destination as? Dismissable
    {
        vc.dismissalDelegate = self
    }
}

这是一个IBaction,它解释了模态vc本身。

    @IBAction func dismiss() {
    dismissalDelegate?.finishedShowing(viewController: self)
    UIView.animate(withDuration: 1.0, animations:{
        (self.dismissalDelegate as! ViewController).dimView.layer.opacity = 0.3
    })
}

1 个答案:

答案 0 :(得分:0)

这只是一个如何完成它的例子。很确定它远非完美,但应该作为一个起点。我有一个旧项目有很多特定的代码,但这可以被删除。

final class ModalSeguePushStyle : UIStoryboardSegue
{
    override func perform() {
        let sourceVC = self.sourceViewController
        let destinationVC = self.destinationViewController
        var endPosition = destinationVC.view.frame
        var startPostition = destinationVC.view.frame

        startPostition.origin.x = startPostition.width

        if sourceVC.navigationController != nil
        {
            startPostition.origin.y = -44
            endPosition.origin.y = -44
        }

        destinationVC.view.frame = startPostition

        sourceVC.view.addSubview(destinationVC.view)

        UIView.animateWithDuration(0.3, animations: { () -> Void in
            destinationVC.view.frame = endPosition
            }) { (Bool) -> Void in
                self.sourceViewController.presentViewController(self.destinationViewController, animated: false, completion: nil)
        }
    }
}

final class ModalSeguePushStyleUnwind : UIStoryboardSegue
{
    func createMockView(view: UIView) -> UIImageView {
        UIGraphicsBeginImageContextWithOptions(view.frame.size, true, UIScreen.mainScreen().scale)

        view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()
        return UIImageView(image: image)
    }

    override func perform() {
        let sourceVC = self.sourceViewController
        let destinationVC = self.destinationViewController
        var endPosition = sourceVC.view.frame

        endPosition.origin.x += endPosition.width

        var bar:UIImageView?
        let mock = createMockView(destinationVC.view)

        if destinationVC.navigationController != nil
        {
            mock.frame.origin.y = 64
        }

        sourceVC.view.superview!.insertSubview(mock, atIndex: 0)

        if let b = destinationVC.tabBarController?.tabBar
        {
            bar = createMockView(b)
            bar?.frame = b.frame
            sourceVC.view.superview!.insertSubview(bar!, aboveSubview: mock)
        }

        UIView.animateWithDuration(0.3, animations: { () -> Void in
            sourceVC.view.frame = endPosition
            }) { (Bool) -> Void in
                sourceVC.dismissViewControllerAnimated(false, completion: { () -> Void in

                })
        }
    }
}