我通过更改自动布局的约束并使用UIView
动画块为其设置动画来设置我的按钮的动画:
UIView.animateWithDuration(0.5, animations: { self.layoutIfNeeded() })
在此动画中,只有按钮的宽度正在变化,而按钮本身也是动画。
在我的按钮中,有一个自定义CAShapeLayer
。是否可以捕捉按钮的动画并将其添加到图层,以便与按钮一起动画?
我尝试过的事情:
// In my CustomButton class
override func actionForLayer(layer: CALayer, forKey event: String) -> CAAction? {
if event == "bounds" {
if let action = super.actionForLayer(layer, forKey: "bounds") as? CABasicAnimation {
let animation = CABasicAnimation(keyPath: event)
animation.fromValue = border.path
animation.toValue = UIBezierPath(rect: bounds).CGPath
// Copy values from existing action
border.addAnimation(animation, forKey: nil) // border is my CAShapeLayer
}
return super.actionForLayer(layer, forKey: event)
}
// In my CustomButton class
override func layoutSubviews() {
super.layoutSubviews()
border.frame = layer.bounds
let fromValue = border.path
let toValue = UIBezierPath(rect: bounds).CGPath
CATransaction.setDisableActions(true)
border.path = toValue
let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = fromValue
animation.toValue = toValue
animation.duration = 0.5
border.addAnimation(animation, forKey: "animation")
}
没有什么工作,我已经挣扎了好几天..
的CustomButton:
class CustomButton: UIButton {
let border = CAShapeLayer()
init() {
super.init(frame: CGRectZero)
translatesAutoresizingMaskIntoConstraints = false
border.fillColor = UIColor.redColor().CGColor
layer.insertSublayer(border, atIndex: 0)
}
// override func layoutSubviews() {
// super.layoutSubviews()
//
// border.frame = layer.bounds
// border.path = UIBezierPath(rect: bounds).CGPath
// }
override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer)
border.frame = self.bounds
border.path = UIBezierPath(rect: bounds).CGPath
}
}
答案 0 :(得分:1)
当您调整视图的背衬图层时,您所要做的就是调整子图层的大小。由于implicit animation,更改应该是动画的。所以你需要做的就是在自定义视图类中设置它:
override func layoutSublayersOfLayer(layer: CALayer!) {
super.layoutSublayersOfLayer(layer)
border.frame = self.bounds
}
<强>更新强>
我有时间玩动画,现在似乎对我有用。这就是它的样子:
class TestView: UIView {
let border = CAShapeLayer()
init() {
super.init(frame: CGRectZero)
translatesAutoresizingMaskIntoConstraints = false
border.backgroundColor = UIColor.redColor().CGColor
layer.insertSublayer(border, atIndex: 0)
border.frame = CGRect(x: 0, y:0, width: 60, height: 60)
backgroundColor = UIColor.greenColor()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer)
CATransaction.begin();
CATransaction.setAnimationDuration(10.0);
border.frame.size.width = self.bounds.size.width
CATransaction.commit();
}
}
我这样使用它:
var tview: TestView? = nil
override func viewDidLoad() {
super.viewDidLoad()
tview = TestView();
tview!.frame = CGRect(x: 100, y: 100, width: 60, height: 60)
view.addSubview(tview!)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.tview!.frame.size.width = 200
}
问题在于frame
的{{1}}属性。文档说:
注意:注 frame属性不能直接设置动画。相反,您应该设置边界,anchorPoint和位置属性的适当组合的动画,以实现所需的结果。
如果你还没有解决你的问题,或者对于其他可能有问题的人,我希望这会有所帮助。