如何在推送segue后让源视图控制器不会消失?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在推送segue后让源视图控制器不会消失?相关的知识,希望对你有一定的参考价值。

首先,这是我的视图控制器/ segue设置:Screenshot of Interface Builder

最右边的三个视图控制器的背景视图是UIVisualEffectViews,源视图控制器应该通过它们可见。他们被添加到各种viewDidLoad()s像这样:

let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

self.tableView.backgroundView = blurEffectView

现在,主视图控制器(“垃圾日”一个)通过设置视图控制器可见,但只要两个最右边的VC中的一个完全在屏幕上,设置VC就会消失。这是一个屏幕录制:

Screen recording of the source view controller dis- and reappearing

(请忽略小故障,我上传的应用程序显然已损坏视频)

我从技术上讲,Show segue没有“Over Current Context”,因此,我不应该期望源VC不会消失,但必须有一种方法可以使这个工作没有自定义segue。

答案

我建议你在视图控制器之间创建一个自定义过渡。

我刚刚编写并测试了这个类:

class AnimationController: NSObject, UIViewControllerAnimatedTransitioning
{
    var pushing = true

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let duration = transitionDuration(using: transitionContext)

        let toVc = transitionContext.viewController(forKey: .to)!
        let toView = transitionContext.view(forKey: .to)!

        let fromView = transitionContext.view(forKey: .from)!

        let container = transitionContext.containerView

        if pushing {
            container.addSubview(fromView)
            container.addSubview(toView)
        }

        var finalFrame = transitionContext.finalFrame(for: toVc)
        if pushing {
            finalFrame.origin.x = finalFrame.width
            toView.frame = finalFrame
            finalFrame.origin.x = 0
        } else {
            finalFrame.origin.x = finalFrame.width
        }

        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
            if self.pushing {
                toView.frame = finalFrame
            } else {
                fromView.frame = finalFrame
            }
        }) { (_) in
            transitionContext.completeTransition(true)
            if self.pushing {
                container.insertSubview(fromView, belowSubview: toView)
            } else {
                fromView.removeFromSuperview()
            }
        }
    }
}

在您的UINavigationController课程中,请执行以下操作:

class NavigationController: UINavigationController {

    let animationController = AnimationController()

    override func viewDidLoad() {
        super.viewDidLoad()

        delegate = self
    }
}

而这个扩展:

extension NavigationController: UINavigationControllerDelegate
{
    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        animationController.pushing = operation == .push

        return animationController
    }
}

但是,这会让您失去交互式关闭手势(从屏幕左侧轻扫以解除)所以您需要自己解决这个问题。

以上是关于如何在推送segue后让源视图控制器不会消失?的主要内容,如果未能解决你的问题,请参考以下文章

Segue 后视图控制器消失

IOS:推送segue后导航栏消失

在地图视图上长按触发推送 segue

推送视图:在发生现有转换或演示时;导航堆栈不会更新

放松Segue隐藏标签栏

从 UINavigationController 中删除动画推送展开?