【问题标题】:Navigation view transition full screen to a view with corner radius导航视图将全屏转换为具有角半径的视图
【发布时间】:2019-09-23 09:21:01
【问题描述】:

我正在尝试从启动画面创建应用主屏幕动画,例如在启动屏幕完成(全)屏幕颜色转换为应用徽标背景颜色后。目前低于我所期望的代码类型存档。但是,这种转换CAShapeLayer 与圆角半径无关。如果没有圆角半径,它可以正常工作,当我尝试使用圆形/椭圆形/圆角半径动画时看起来像下面的 gif。

尝试了一些其他 StackOverflow 答案,这些答案创建了不起作用的圆形动画。 Here one of those.

    weak var viewTransitionContext: UIViewControllerContextTransitioning!

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        viewTransitionContext = transitionContext

        guard let fromVC = viewTransitionContext.viewController(forKey: .from) else { return }
        guard let toVC = viewTransitionContext.viewController(forKey: .to) else { return }

        if fromVC.isKind(of: SOGSplashViewController.self) && toVC.isKind(of: SOGHomeViewController.self) {
            guard let toVCView = transitionContext.view(forKey: .to) else { return }
            guard let fromVCView = transitionContext.view(forKey: .from) else { return }

            let containerView = transitionContext.containerView
            let labelWidth = UIDevice.width() * 0.75
            let labelHeight = labelWidth * 0.7
            let xAxis = (UIDevice.width() - labelWidth)/2.0
            let yAxis = ((UIDevice.height()/2.0) - labelHeight)/2.0
            let labelRect = CGRect(x: xAxis, y: yAxis, width: labelWidth, height: labelHeight)
            let radius = (UIDevice.height()/2.0)*0.1
            let fromFrame = fromVCView.bounds
            let animationTime = transitionDuration(using: transitionContext)

            let maskLayer = CAShapeLayer()
            maskLayer.isOpaque = false
            maskLayer.fillColor = fromVCView.backgroundColor?.cgColor
            maskLayer.backgroundColor = UIColor.clear.cgColor
            maskLayer.path = toPathValue.cgPath

            let maskAnimationLayer = CABasicAnimation(keyPath: "path")
            maskAnimationLayer.fromValue = (UIBezierPath(rect: fromFrame)).cgPath
            maskAnimationLayer.toValue = toPathValue.cgPath
            maskAnimationLayer.duration = animationTime
            maskAnimationLayer.delegate = self as? CAAnimationDelegate

            containerView.addSubview(fromVCView)
            containerView.addSubview(toVCView)
            fromVCView.layer.add(maskAnimationLayer, forKey: nil)
            maskLayer.add(maskAnimationLayer, forKey: "path")
            containerView.layer.addSublayer(maskLayer)

            let deadLineTime = DispatchTime.now() + .seconds(1)
            DispatchQueue.main.asyncAfter(deadline: deadLineTime) {
                UIView.animate(withDuration: 0.2, animations: {
                    maskLayer.opacity = 0
                }, completion: { (isSuccess) in
                    self.viewTransitionContext.completeTransition(true)
                })
            }
        }
    }

【问题讨论】:

    标签: swift navigation uibezierpath cashapelayer caanimation


    【解决方案1】:

    如果您通过 Core Animation 之类的通用方式将矩形路径转换为圆角矩形路径是一项非常复杂的操作。您最好使用可动画化的CALayercornerRadius 属性。

    这是一个基于约束的动画的工作示例:

    class ViewController: UIViewController {
        @IBOutlet var constraints: [NSLayoutConstraint]!
        @IBOutlet var contentView: UIView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func viewDidAppear(_ animated: Bool) {
            self.contentView.layer.cornerRadius = 10.0
            self.animate(nil)
        }
    
        @IBAction func animate(_ sender: Any?) {
            for c in constraints {
                c.constant = 40.0
            }
            UIView.animate(withDuration: 4.0) {
                self.view.layoutIfNeeded()
                self.contentView.layer.cornerRadius = 40.0
            }
        }
    }
    

    contentView 指向应该动画的内部视图,constraints 指的是定义视图控制器视图到内容视图距离的四个布局约束。

    这只是一个简单粗略的例子,当然可以改进。

    【讨论】:

    • 感谢您的选择。最初我只尝试了基于约束的动画。多一个屏幕也有这样的动画(今天的应用商店首页),如果在UIViewControllerContextTransitioning上做的话,向后滑动或点击后退按钮动画会更容易@
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多