当前位置: 首页 > 知识库问答 >
问题:

扩展UIView时出现奇怪的动画

韦澄邈
2023-03-14

我有一个XUIView课程,如下所示。运行动画时,对折叠没有效果。

谁能解释我?

class ViewController: UIViewController {

    // Width constraint of XUIView instance
    @IBOutlet weak var vwWrapperWidth: NSLayoutConstraint! {
        didSet{
            self.vwWrapperWidth.constant = UIScreen.main.bounds.width
        }
    }

    @IBAction func btnToggleTouchUp(_ sender: UIButton) {
        if(self.vwWrapperWidth.constant == 55) {
            // animation effect is OK when expanding
            self.vwWrapperWidth.constant = UIScreen.main.bounds.width

            UIView.animate(withDuration: 0.5, animations: {
                self.view.layoutIfNeeded()
            })
        }
        else {
            // animation effect is not OK when folding
            self.vwWrapperWidth.constant = 55
            UIView.animate(withDuration: 0.5, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }
    //.....
}

@IBDesignable
class XUIView: UIView {

    @IBInspectable
    var roundTopLeftCorner: Bool = false

    @IBInspectable
    var roundBottomLeftCorner: Bool = false

    @IBInspectable
    var roundTopRightCorner: Bool = false

    @IBInspectable
    var roundBottomRightCorner: Bool = false

    @IBInspectable
    var cornerRadius: 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

        self.layer.mask = maskLayer

        self.borderLayer?.frame = bounds
        self.borderLayer?.path = maskPath.cgPath
        self.borderLayer?.strokeColor = self.borderColor?.cgColor
        self.borderLayer?.lineWidth = self.borderWidth
        self.borderLayer?.fillColor = nil

    }

    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) }
        roundCorners(roundedCorners)
    }


}

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

共有2个答案

杨景山
2023-03-14

问题是您正在布局子视图中创建一个CAShapeLayer,这意味着每次动画发生时,它都会被调用。

试着评论第91行,你会得到你想要的。

夏侯英纵
2023-03-14

您在“折叠”动画上没有遇到任何动画,因为CALayer的路径属性不能隐式设置动画。这里提到了这一点。

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

最糟糕的是,CALayer的frame属性也不能隐式设置动画。这里提到了

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

这仅仅意味着以下几行行不通,因为它是在UIView中调用的。设置块的动画。

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中的layoutSubview方法,就会应用掩码。视图实际上是动画的,但您只是看不到它,因为在动画完成之前正在设置掩码。

这也是展开动画中发生的情况。首先,遮罩展开,然后出现动画。

要防止出现这种情况,可能需要找到一种方法来设置宽度约束和层帧的动画

 类似资料:
  • 问题内容: 在Python(2.7)中发现了从未有过的有趣的东西。 这个: 确实有效,结果是: 但 给 有人可以解释为什么吗?感谢您的回答。 问题答案: Python区分和运算符,并为它们提供了单独的挂钩。和。该类型只是为后者提供了不同的实现。 列表分别实现这些功能更为有效;必须返回一个全新的列表,而可以扩展然后返回。 在C代码中,是由所实现的,该只需调用,或者在python代码中,由。后者根据设

  • 问题内容: 我有这种方法,它使用字符串的可变参数,从中创建一个列表,然后尝试删除列表的第一个元素。 但是,一旦被调用,就会抛出一个。我的猜测是返回的List- Type不支持remove方法。我对么?我有什么选择? 问题答案: 仅在数组周围提供薄包装。该包装器使您可以使用API 对阵列执行 大多数 操作。JavaDoc的引文: 返回由指定数组支持的 固定大小的 列表。[…]此方法充当基于数组的AP

  • 问题内容: 我有这种方法,它使用字符串的可变参数,从中创建一个列表,然后尝试删除列表的第一个元素。 但是,一旦被调用,就会抛出一个。我的猜测是返回的List- Type不支持remove方法。我对么?我有什么选择? 问题答案: 仅在数组周围提供薄包装。该包装器使您可以使用API 对阵列执行 大多数 操作。JavaDoc的引文: 返回由指定数组支持的 固定大小的 列表。[…]此方法充当基于数组的AP

  • 在JSX中使用spread操作符react处理之类的对象似乎无法输出我所期望的结果。 似乎被渲染为,其中应该是,如本文所述。我在任何地方都找不到这个文件。我对react完全是新手,我试图理解它的语法,想知道react是否在内部做了类似这样的未记录的事情。 一个简单的测试突显了我的困惑: 警报了 1. 这肯定不会编译:

  • 我在使用FPDF库生成pdf文件时得到了这个输出。 %PDF-1.3.0 obj 我的代码: