以 Swift 为中心制作一个圆圈
Animate a circle from the center in Swift
我有一个正在制作动画的圆圈。它的工作原理除了绘图是从左上角开始的。我可以从中心为它制作动画吗?如果是这样,任何帮助将不胜感激..
我画圆的代码是:
class CircleView: UIView {
override func draw(_ rect: CGRect)
{
let prefs: UserDefaults = UserDefaults.standard
lineWidthFloat = prefs.value(forKey: "lineWidth") as! Float
let circleSize = Double(lineWidthFloat * 100)
let context = UIGraphicsGetCurrentContext()
context!.setLineWidth(10.0)
context!.setFillColor(UIColor.black.cgColor)
let rect = CGRect(x: 20, y: 20, width: circleSize, height: circleSize)
context!.addEllipse(inRect: rect)
context!.fillPath()
}
}
谢谢!
详情
- Xcode 10.2.1 (10E1001), Swift 5
完整样本
CircleView
class CircleView: UIView {
weak var circleView: UIView?
lazy var isAnimating = false
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func setup() {
let rectSide = (frame.size.width > frame.size.height) ? frame.size.height : frame.size.width
let circleRect = CGRect(x: (frame.size.width-rectSide)/2, y: (frame.size.height-rectSide)/2, width: rectSide, height: rectSide)
let circleView = UIView(frame: circleRect)
circleView.backgroundColor = UIColor.yellow
circleView.layer.cornerRadius = rectSide/2
circleView.layer.borderWidth = 2.0
circleView.layer.borderColor = UIColor.red.cgColor
addSubview(circleView)
self.circleView = circleView
}
func resizeCircle (summand: CGFloat) {
guard let circleView = circleView else { return }
frame.origin.x -= summand/2
frame.origin.y -= summand/2
frame.size.height += summand
frame.size.width += summand
circleView.frame.size.height += summand
circleView.frame.size.width += summand
}
private func animateChangingCornerRadius (toValue: Any?, duration: TimeInterval) {
guard let circleView = circleView else { return }
let animation = CABasicAnimation(keyPath:"cornerRadius")
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
animation.fromValue = circleView.layer.cornerRadius
animation.toValue = toValue
animation.duration = duration
circleView.layer.cornerRadius = circleView.frame.size.width/2
circleView.layer.add(animation, forKey:"cornerRadius")
}
private func circlePulseAinmation(_ summand: CGFloat, duration: TimeInterval, completionBlock:@escaping ()->()) {
guard let circleView = circleView else { return }
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseInOut, animations: { [weak self] in
self?.resizeCircle(summand: summand)
}) { _ in completionBlock() }
animateChangingCornerRadius(toValue: circleView.frame.size.width/2, duration: duration)
}
func resizeCircleWithPulseAinmation(_ summand: CGFloat, duration: TimeInterval) {
if (!isAnimating) {
isAnimating = true
circlePulseAinmation(summand, duration:duration) { [weak self] in
guard let self = self else { return }
self.circlePulseAinmation((-1)*summand, duration:duration) {self.isAnimating = false}
}
}
}
}
ViewController
import UIKit
class ViewController: UIViewController {
weak var circleView: CircleView?
weak var button: UIButton?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let circleView = CircleView(frame: CGRect(x: 40, y: 50, width: 40, height: 60))
circleView.backgroundColor = UIColor.clear
view.addSubview(circleView)
self.circleView = circleView
let button = UIButton(frame: CGRect(x: 20, y: 150, width: 80, height: 40))
button.setTitle("Animate", for: UIControl.State())
button.setTitleColor(UIColor.blue, for: UIControl.State())
button.setTitleColor(UIColor.blue.withAlphaComponent(0.3), for: .highlighted)
button.addTarget(self, action: #selector(ViewController.animateCircle), for: .touchUpInside)
view.addSubview(button)
self.button = button
}
@objc func animateCircle() {
circleView?.resizeCircleWithPulseAinmation(30, duration: 1.5)
}
}
结果
使用变换 属性。
你应该能够更简单地完成它
func pulse() {
UIView.animate(withDuration: 0.5, animations:{
self.circleView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
}, completion: { _ in
UIView.animate(withDuration: 0.5, animations: {
self.circleView.transform = .identity
})
})
}
我有一个正在制作动画的圆圈。它的工作原理除了绘图是从左上角开始的。我可以从中心为它制作动画吗?如果是这样,任何帮助将不胜感激..
我画圆的代码是:
class CircleView: UIView {
override func draw(_ rect: CGRect)
{
let prefs: UserDefaults = UserDefaults.standard
lineWidthFloat = prefs.value(forKey: "lineWidth") as! Float
let circleSize = Double(lineWidthFloat * 100)
let context = UIGraphicsGetCurrentContext()
context!.setLineWidth(10.0)
context!.setFillColor(UIColor.black.cgColor)
let rect = CGRect(x: 20, y: 20, width: circleSize, height: circleSize)
context!.addEllipse(inRect: rect)
context!.fillPath()
}
}
谢谢!
详情
- Xcode 10.2.1 (10E1001), Swift 5
完整样本
CircleView
class CircleView: UIView {
weak var circleView: UIView?
lazy var isAnimating = false
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func setup() {
let rectSide = (frame.size.width > frame.size.height) ? frame.size.height : frame.size.width
let circleRect = CGRect(x: (frame.size.width-rectSide)/2, y: (frame.size.height-rectSide)/2, width: rectSide, height: rectSide)
let circleView = UIView(frame: circleRect)
circleView.backgroundColor = UIColor.yellow
circleView.layer.cornerRadius = rectSide/2
circleView.layer.borderWidth = 2.0
circleView.layer.borderColor = UIColor.red.cgColor
addSubview(circleView)
self.circleView = circleView
}
func resizeCircle (summand: CGFloat) {
guard let circleView = circleView else { return }
frame.origin.x -= summand/2
frame.origin.y -= summand/2
frame.size.height += summand
frame.size.width += summand
circleView.frame.size.height += summand
circleView.frame.size.width += summand
}
private func animateChangingCornerRadius (toValue: Any?, duration: TimeInterval) {
guard let circleView = circleView else { return }
let animation = CABasicAnimation(keyPath:"cornerRadius")
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
animation.fromValue = circleView.layer.cornerRadius
animation.toValue = toValue
animation.duration = duration
circleView.layer.cornerRadius = circleView.frame.size.width/2
circleView.layer.add(animation, forKey:"cornerRadius")
}
private func circlePulseAinmation(_ summand: CGFloat, duration: TimeInterval, completionBlock:@escaping ()->()) {
guard let circleView = circleView else { return }
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseInOut, animations: { [weak self] in
self?.resizeCircle(summand: summand)
}) { _ in completionBlock() }
animateChangingCornerRadius(toValue: circleView.frame.size.width/2, duration: duration)
}
func resizeCircleWithPulseAinmation(_ summand: CGFloat, duration: TimeInterval) {
if (!isAnimating) {
isAnimating = true
circlePulseAinmation(summand, duration:duration) { [weak self] in
guard let self = self else { return }
self.circlePulseAinmation((-1)*summand, duration:duration) {self.isAnimating = false}
}
}
}
}
ViewController
import UIKit
class ViewController: UIViewController {
weak var circleView: CircleView?
weak var button: UIButton?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let circleView = CircleView(frame: CGRect(x: 40, y: 50, width: 40, height: 60))
circleView.backgroundColor = UIColor.clear
view.addSubview(circleView)
self.circleView = circleView
let button = UIButton(frame: CGRect(x: 20, y: 150, width: 80, height: 40))
button.setTitle("Animate", for: UIControl.State())
button.setTitleColor(UIColor.blue, for: UIControl.State())
button.setTitleColor(UIColor.blue.withAlphaComponent(0.3), for: .highlighted)
button.addTarget(self, action: #selector(ViewController.animateCircle), for: .touchUpInside)
view.addSubview(button)
self.button = button
}
@objc func animateCircle() {
circleView?.resizeCircleWithPulseAinmation(30, duration: 1.5)
}
}
结果
使用变换 属性。
你应该能够更简单地完成它func pulse() {
UIView.animate(withDuration: 0.5, animations:{
self.circleView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
}, completion: { _ in
UIView.animate(withDuration: 0.5, animations: {
self.circleView.transform = .identity
})
})
}