【发布时间】:2021-02-26 07:53:08
【问题描述】:
考虑一个国际象棋游戏。一个独立的ViewController 和一个ChessPieceView 出现在下面。 (在我的 Xcode 10 上,Playgrounds 不支持图形,因此使用了一个成熟的,即使是微不足道的项目。)
我们为棋子的运动设置动画。我们还想为围绕它的圆圈的颜色设置动画(用于国际象棋教程等)。
我们在这里为View.backgroundColor 制作动画。但我们真正想做的是为圆的填充颜色设置动画。这件作品的backgroundColor 将是 from/to 方块的填充颜色,无论它们是什么。
// ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let rect = CGRect(origin: CGPoint(x: 100, y: 100),
size: CGSize(width: 100, height: 100))
let chessPieceView = ChessPieceView.init(fromFrame: rect)
self.view.addSubview(chessPieceView)
}
}
// ChessPieceView.swift
import UIKit
class ChessPieceView: UIView {
init(fromFrame frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.cyan
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
let circle = UIBezierPath(arcCenter: CGPoint(x: bounds.midX, y: bounds.midY),
radius: 30,
startAngle: 0, endAngle: CGFloat.pi*2,
clockwise: false)
UIColor.red.setFill()
circle.fill()
}
override func layoutSubviews() {
super.layoutSubviews()
addGestureRecognizer(UITapGestureRecognizer(target: self,
action: #selector(tapPiece(_ :))))
}
@objc func tapPiece(_ gestureRecognizer : UITapGestureRecognizer ) {
guard gestureRecognizer.view != nil else { return }
if gestureRecognizer.state == .ended {
let animator = UIViewPropertyAnimator(duration: 1.2,
curve: .easeInOut,
animations: {
self.center.x += 100
self.center.y += 200
})
animator.startAnimation()
UIView.animate(withDuration: 1.2) {
self.backgroundColor = UIColor.yellow
}
}
}
}
困难出现在"can't animate the fill color of a UIBezierPath directly"。那是因为,iOS 似乎根本不会重新渲染(也就是重新扫描转换)路径。当请求动画时,会改为执行(相对便宜的)合成操作。
【问题讨论】:
标签: ios swift animation uiview