使用 CATransition self.dismiss 时隐藏黑色渐变

Hide a black fade when self.dismiss with CATransition

我想让我的 viewController 变成带动画的旧 viewController。但是当我使用 CATransition 时,我的 viewController 和旧的 viewController 变黑了。有什么办法让它不掉色吗?

let transition = CATransition()
transition.duration = 1.0
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
view.window!.layer.add(transition, forKey: kCATransition)
self.dismiss(animated: false, completion: nil)

详细了解转换 here 并尝试修改可用参数以获得所需的效果。

有关转换的良好未记录信息 available here

如果您想要一些好的解决方案 - 您应该为您的屏幕准备自定义过渡 - 检查此 WWDC video

另一种快速(但不是最佳)解决方案可能是在 viewController 中手动控制 presentation/dismiss:

import UIKit

final class AnimatableViewController: UIViewController {

    private var panStartLocation:CGPoint = CGPoint.zero
    private var panPrevLocation:CGPoint = CGPoint.zero

    var onClose:(()->())?

    // MARK: - LifeCycle

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        openAnimation()
    }

    // MARK: - IBAction

    @objc private func closeButtonAction(_ sender: UIButton) {
        dismiss(animated: true, completion: { [weak self] in
            self?.onClose?()
        })
    }

    // MARK: - Gestures

    @IBAction private func didDetectPan(_ sender: UIPanGestureRecognizer) {
        switch sender.state {
            case .began:
                panStartLocation = sender.location(in: navigationController?.view)
                panPrevLocation = panStartLocation
            case .cancelled, .ended:
                finishAnimation()
            case .changed:
                let newPoint:CGPoint = sender.location(in: navigationController?.view)
                let dy:CGFloat = newPoint.y - panPrevLocation.y
                var newPosition:CGPoint = view.center

                if (newPoint.y - panStartLocation.y > 0) {
                    newPosition.y += dy
                } else {
                    newPosition.y = self.view.bounds.height / 2
                }
                view.center = newPosition
                panPrevLocation = newPoint
            default:
                break
        }
    }

    //MARK: Animation

    private func finishAnimation() {
        let center:CGPoint = view.center
        if (center.y > self.view.bounds.height / 2 * 1.35) {
            closeAnimation()
        } else {
            openAnimation()
        }
    }

    private func closeAnimation() {
        let fullAnimTime:CGFloat = 0.5
        let endPoint:CGPoint = CGPoint(x:view.center.x, y:view.bounds.height / 2 * 3)
        let animTime:CGFloat = ((endPoint.y - view.center.y) / self.view.bounds.height) * fullAnimTime

        UIView.animate(withDuration: TimeInterval(animTime), animations: { [weak self] in
            self?.view.center = endPoint
            }, completion: { [weak self] _ in
                self?.dismiss(animated: false, completion: {
                    self?.onClose?()
                })
        })
    }

    private func openAnimation() {
        let fullAnimTime:CGFloat = 0.5
        let endPoint:CGPoint = CGPoint(x: view.center.x, y:self.view.bounds.height / 2)
        let animTime:CGFloat = ((view.center.y - endPoint.y) / (self.view.bounds.height / 2)) * fullAnimTime
        UIView.animate(withDuration: TimeInterval(animTime)) { [weak self] in
            self?.view.center = endPoint
        }
    }
}

extension AnimatableViewController: UIGestureRecognizerDelegate {
    // MARK: - UIGestureRecognizerDelegate

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        if gestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer is UIPanGestureRecognizer {
            return false
        }
        return true
    }
}

在情节提要中,不要忘记将 segue 参数设置为:

并将 panGesture 添加到您的根视图或将任何其他平移手势添加到最顶部的视图,可用于平移 - 在我的例子中 - 我只是将平移添加到 rootView:

结果: