swift - 导航视图将全屏转换为具有角半径的视图
问题描述
我正在尝试从启动画面创建应用程序主屏幕动画,例如在启动屏幕完成(全)屏幕颜色转换为应用程序徽标背景颜色后。目前低于我所期望的代码类型的存档。但是,这种转换CAShapeLayer
与圆角半径无关。如果没有圆角半径,它可以正常工作,当我尝试使用圆形/椭圆形/圆角半径动画时,它看起来像下面的 gif。
尝试了一些其他 StackOverflow 答案,这些答案创建了那些不起作用的圆形动画。这是其中之一。
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)
})
}
}
}
解决方案
如果您通过 Core Animation 之类的通用方式将矩形路径转换为圆角矩形路径是一个非常复杂的操作。您最好使用其cornerRadius
属性CALayer
是可动画的。
这是一个基于约束的动画的工作示例:
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
参考定义从视图控制器的视图到内容视图的距离的四个布局约束。
这只是一个简单粗略的例子,当然可以改进。
推荐阅读
- android - 如何使用 rxJava2 在一个请求中发出两个请求
- python - 如何将mysql局部变量传递给python?
- python - 使用静态照片的 Haar 分类器进行眼睛识别
- graph - 找到最大权重子图
- typescript - 如何将 json 对象映射到 typescript 数组
- java - commons math3 和 ojalgo 库的 SVD 解决方案输出之间的巨大差异
- javascript - 我们什么时候需要在 JavaScript OOP 中使用“get”关键字
- c# - 如何通过左右滑动来修复移动?
- amazon-web-services - 寻找使用 AWS CLI 提取 AWS 安全组列表及其入站/出站规则的命令
- powershell - 如何创建自签名证书?