扩展 UIView 时出现奇怪的动画

  • 本文关键字:动画 UIView 扩展 swift
  • 更新时间 :
  • 英文 :


我有一个XUIView类如下。当我运行动画时,它对折叠没有影响。

谁能解释我?

类视图控制器: UIViewController { XUIView 实例的宽度约束 @IBOutlet weak var vwWrapperWidth: NSLayoutConstraint!{ didSet{ self.vwWrapperWidth.constant = UIScreen.main.bounds.width } } @IBAction func btnToggleTouchUp(_ sender: UIButton( { if(self.vwWrapperWidth.constant == 55( { 展开时动画效果还可以 self.vwWrapperWidth.constant = UIScreen.main.bounds.width UIView.animate(与持续时间: 0.5, 动画: { self.view.layoutIfNeed(( }) } 否则 { 折叠时动画效果不行 self.vwWrapperWidth.constant = 55 UIView.animate(与持续时间: 0.5, 动画: { self.view.layoutIfNeed(( }) } }//..... } @IBDesignable 类 XUIView: UIView { @IBInspectable var roundTopLeftCorner: bool = false @IBInspectable var roundDownLeftCorner: bool = false @IBInspectable var roundTopRightCorner: bool = false @IBInspectable var round右下角:布尔值 = 假 @IBInspectable 变量角半径:CGFloat = 0.0 @IBInspectable var borderWidth: CGFloat = 0.0 @IBInspectable var borderColor: UIColor? fileprivate var borderLayer: CAShapeLayer?{ didSet{ self.layer.addSublayer(self.borderLayer!( } } func roundCorners(_ corners: UIRectCorner( { if(self.borderLayer == nil( { self.borderLayer = CAShapeLayer(( } let bounds = self.bounds let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: self.cornerRadius, height: self.cornerRadius(( let maskLayer = CAShapeLayer(( maskLayer.frame = bounds maskLayer.path = maskPath.cgPath 自我.层.掩码 = 掩码层 自我边界层?.帧 = 边界 自我边界层?.path = maskPath.cgPath 自我边界层?.笔触颜色 = self.borderColor?.cg颜色 自我边界层?.lineWidth = self.borderWidth 自我边界层?.填充颜色 = 无 } override func layoutSubviews(( { super.layoutSubviews(( var roundedCorners: UIRectCorner = [] if(roundTopLeftCorner( { roundedCorners.insert(.topLeft( } if(roundTopRightCorner( { roundedCorners.insert(.topRight( } if(roundBottomLeftCorner( { roundedCorners.insert(.bottomLeft( } if(roundBottomRightCorner( { roundedCorners.insert(.bottomRight( } 圆角(圆角( } }

源代码 : http://www.mediafire.com/file/n6svp1mk44fc0uf/TestXUIView.zip/file

您在"折叠"动画上没有遇到动画CALayer因为path属性不是隐式动画的。这里提到了它。

与大多数可设置动画的属性不同,path (与所有 CGPath 可动画属性一样(不支持隐式动画。

更糟糕的是,CALayerframe属性也不是隐含的动画。这里提到

: 帧属性不能直接进行动画处理。相反,您应该对边界、锚点和位置属性的适当组合进行动画处理,以实现所需的结果。

这只是意味着以下行不起作用,只是因为它是在UIView.animate块中调用的。

let maskLayer = CAShapeLayer()
maskLayer.frame = bounds // This line won't animate!
maskLayer.path = maskPath.cgPath // This line won't animate!
self.layer.mask = maskLayer

由于它没有被动画化,因此一旦调用XUIView中的layoutSubviews方法,就会应用蒙版。视图实际上是动画,但您只是看不到它,因为在动画完成之前设置了蒙版。

这也是扩展动画中发生的情况。首先蒙版展开,然后动画发生。

为了防止这种情况,您可能需要找到一种方法来同时对宽度约束和图层框架遮罩路径进行动画处理。

问题是您正在layoutSubviews中创建CAShapeLayer,这意味着每次动画发生时都会被调用。

尝试注释第 91 行,您将得到您想要的。

最新更新