원의 애니메이션 그리기
저는 원을 그리는 애니메이션을 만드는 방법을 찾고 있습니다.저는 원을 만들 수 있었지만, 그것은 모든 것을 하나로 묶습니다.
제 기내꺼입니다.CircleView
클스래:
import UIKit
class CircleView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.clearColor()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func drawRect(rect: CGRect) {
// Get the Graphics Context
var context = UIGraphicsGetCurrentContext();
// Set the circle outerline-width
CGContextSetLineWidth(context, 5.0);
// Set the circle outerline-colour
UIColor.redColor().set()
// Create Circle
CGContextAddArc(context, (frame.size.width)/2, frame.size.height/2, (frame.size.width - 10)/2, 0.0, CGFloat(M_PI * 2.0), 1)
// Draw
CGContextStrokePath(context);
}
}
다음은 내 보기 컨트롤러의 보기 계층에 추가하는 방법입니다.
func addCircleView() {
let diceRoll = CGFloat(Int(arc4random_uniform(7))*50)
var circleWidth = CGFloat(200)
var circleHeight = circleWidth
// Create a new CircleView
var circleView = CircleView(frame: CGRectMake(diceRoll, 0, circleWidth, circleHeight))
view.addSubview(circleView)
}
원을 그리는 것을 1초에 걸쳐 애니메이션화할 수 있는 방법이 방법이 있습니까?
예를 들어, 애니메이션 전체를 보면 다음 이미지의 파란색 선처럼 보입니다.
가장 쉬운 방법은 코어 애니메이션의 기능을 사용하여 대부분의 작업을 수행하는 것입니다.의 원 를 그기위는당원의그코당드리신것옮할것다입니에서 옮겨야 할 것입니다.drawRect
…의 기능을 다하다그런 다음, 우리는 a를 사용하여 애니메이션을 만들 수 있습니다.CAShapeLayer
의 재산.0.0
1.0
.strokeEnd
여기 마법의 큰 부분을 차지합니다. 문서에서:
strokeStart 속성과 결합된 이 속성은 스트로크 경로의 하위 영역을 정의합니다.이 속성의 값은 strokeStart 속성이 시작점을 정의하는 동안 스트로크를 완료할 경로의 상대점을 나타냅니다.0.0 값은 경로의 시작을 나타내고 1.0 값은 경로의 끝을 나타냅니다.사이의 값은 경로 길이를 따라 선형으로 해석됩니다.
우리가 설정하면,strokeEnd
0.0
아무것도 그릴 수 없습니다.으로 하면,1.0
전체 원을 그리게 될 겁니다.으로 하면,0.5
그것은 반원을 그릴 것입니다.기타.
시작하려면 다음과 같이 하십시오.CAShapeLayer
의 신의에CircleView
의init
의 기하고을뷰추가에 합니다.sublayers
( (으)는 반드시 drawRect
이제 도면층이 원을 그릴 것이므로 함수):
let circleLayer: CAShapeLayer!
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.clearColor()
// Use UIBezierPath as an easy way to create the CGPath for the layer.
// The path should be the entire circle.
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(Double.pi * 2.0), clockwise: true)
// Setup the CAShapeLayer with the path, colors, and line width
circleLayer = CAShapeLayer()
circleLayer.path = circlePath.CGPath
circleLayer.fillColor = UIColor.clearColor().CGColor
circleLayer.strokeColor = UIColor.redColor().CGColor
circleLayer.lineWidth = 5.0;
// Don't draw the circle initially
circleLayer.strokeEnd = 0.0
// Add the circleLayer to the view's layer's sublayers
layer.addSublayer(circleLayer)
}
참고: 설정 중입니다.circleLayer.strokeEnd = 0.0
원이 바로 그려지지 않도록 말입니다.
이제 원 애니메이션을 트리거하기 위해 호출할 수 있는 기능을 추가하겠습니다.
func animateCircle(duration: NSTimeInterval) {
// We want to animate the strokeEnd property of the circleLayer
let animation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.strokeEnd))
// Set the animation duration appropriately
animation.duration = duration
// Animate from 0 (no circle) to 1 (full circle)
animation.fromValue = 0
animation.toValue = 1
// Do a linear animation (i.e. the speed of the animation stays the same)
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
// Set the circleLayer's strokeEnd property to 1.0 now so that it's the
// right value when the animation ends.
circleLayer.strokeEnd = 1.0
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
}
그러면, 우리가 해야 할 일은 당신의 것을 바꾸는 것입니다.addCircleView
추가할 때 애니메이션을 트리거하는 기능CircleView
자체적으로superview
:
func addCircleView() {
let diceRoll = CGFloat(Int(arc4random_uniform(7))*50)
var circleWidth = CGFloat(200)
var circleHeight = circleWidth
// Create a new CircleView
var circleView = CircleView(frame: CGRectMake(diceRoll, 0, circleWidth, circleHeight))
view.addSubview(circleView)
// Animate the drawing of the circle over the course of 1 second
circleView.animateCircle(1.0)
}
모든 구성 요소는 다음과 같이 표시되어야 합니다.
참고: 그런 식으로 반복되지는 않을 것입니다. 애니메이션을 만든 후에도 전체 원을 유지할 것입니다.
Mikes 응답이 Swift 3.0용으로 업데이트되었습니다.
var circleLayer: CAShapeLayer!
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.clear
// Use UIBezierPath as an easy way to create the CGPath for the layer.
// The path should be the entire circle.
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(M_PI * 2.0), clockwise: true)
// Setup the CAShapeLayer with the path, colors, and line width
circleLayer = CAShapeLayer()
circleLayer.path = circlePath.cgPath
circleLayer.fillColor = UIColor.clear.cgColor
circleLayer.strokeColor = UIColor.red.cgColor
circleLayer.lineWidth = 5.0;
// Don't draw the circle initially
circleLayer.strokeEnd = 0.0
// Add the circleLayer to the view's layer's sublayers
layer.addSublayer(circleLayer)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func animateCircle(duration: TimeInterval) {
// We want to animate the strokeEnd property of the circleLayer
let animation = CABasicAnimation(keyPath: "strokeEnd")
// Set the animation duration appropriately
animation.duration = duration
// Animate from 0 (no circle) to 1 (full circle)
animation.fromValue = 0
animation.toValue = 1
// Do a linear animation (i.e The speed of the animation stays the same)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
// Set the circleLayer's strokeEnd property to 1.0 now so that it's the
// Right value when the animation ends
circleLayer.strokeEnd = 1.0
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
}
함수 호출하기
func addCircleView() {
let diceRoll = CGFloat(Int(arc4random_uniform(7))*50)
var circleWidth = CGFloat(200)
var circleHeight = circleWidth
// Create a new CircleView
let circleView = CircleView(frame: CGRect(x: diceRoll, y: 0, width: circleWidth, height: circleHeight))
//let test = CircleView(frame: CGRect(x: diceRoll, y: 0, width: circleWidth, height: circleHeight))
view.addSubview(circleView)
// Animate the drawing of the circle over the course of 1 second
circleView.animateCircle(duration: 1.0)
}
마이크의 대답은 훌륭합니다!이를 위한 또 다른 멋지고 간단한 방법은 drawRect를 setNeedsDisplay()와 결합하여 사용하는 것입니다.느린 것 같지만 그렇지 않습니다 :-)
우리는 위에서 시작해서 -90°에서 270°로 끝나는 원을 그리고 싶습니다.원의 중심은 주어진 반지름을 가진 (중심 X, 중심 Y)입니다.CurrentAngle은 minAngle(-90)에서 maxAngle(270)까지 원의 끝점의 현재 각도입니다.
// MARK: Properties
let centerX:CGFloat = 55
let centerY:CGFloat = 55
let radius:CGFloat = 50
var currentAngle:Float = -90
let minAngle:Float = -90
let maxAngle:Float = 270
drawRect에서 원이 표시되는 방식을 지정합니다.
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
let path = CGPathCreateMutable()
CGPathAddArc(path, nil, centerX, centerY, radius, CGFloat(GLKMathDegreesToRadians(minAngle)), CGFloat(GLKMathDegreesToRadians(currentAngle)), false)
CGContextAddPath(context, path)
CGContextSetStrokeColorWithColor(context, UIColor.blueColor().CGColor)
CGContextSetLineWidth(context, 3)
CGContextStrokePath(context)
}
문제는 현재 currentAngle이 변경되지 않기 때문에 currentAngle = minAngle처럼 원이 정적이고 표시되지도 않는다는 것입니다.
그런 다음 타이머를 만들고 타이머가 작동할 때마다 전류 각도를 늘립니다.클래스의 맨 위에 두 화재 사이의 타이밍을 추가합니다.
let timeBetweenDraw:CFTimeInterval = 0.01
init에 타이머를 추가합니다.
NSTimer.scheduledTimerWithTimeInterval(timeBetweenDraw, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
타이머가 작동할 때 호출되는 기능을 추가할 수 있습니다.
func updateTimer() {
if currentAngle < maxAngle {
currentAngle += 1
}
}
안타깝게도 앱을 실행할 때 다시 그릴 시스템을 지정하지 않았기 때문에 아무것도 표시되지 않습니다.이 작업은 setNeedsDisplay()를 호출하여 수행됩니다.다음은 업데이트된 타이머 기능입니다.
func updateTimer() {
if currentAngle < maxAngle {
currentAngle += 1
setNeedsDisplay()
}
}
_ _ _
필요한 모든 코드가 여기에 요약되어 있습니다.
import UIKit
import GLKit
class CircleClosing: UIView {
// MARK: Properties
let centerX:CGFloat = 55
let centerY:CGFloat = 55
let radius:CGFloat = 50
var currentAngle:Float = -90
let timeBetweenDraw:CFTimeInterval = 0.01
// MARK: Init
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
func setup() {
self.backgroundColor = UIColor.clearColor()
NSTimer.scheduledTimerWithTimeInterval(timeBetweenDraw, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
}
// MARK: Drawing
func updateTimer() {
if currentAngle < 270 {
currentAngle += 1
setNeedsDisplay()
}
}
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
let path = CGPathCreateMutable()
CGPathAddArc(path, nil, centerX, centerY, radius, -CGFloat(M_PI/2), CGFloat(GLKMathDegreesToRadians(currentAngle)), false)
CGContextAddPath(context, path)
CGContextSetStrokeColorWithColor(context, UIColor.blueColor().CGColor)
CGContextSetLineWidth(context, 3)
CGContextStrokePath(context)
}
}
속도를 변경하려면 업데이트를 수정하십시오.타이머 기능 또는 이 기능이 호출되는 속도입니다.또한 원이 완성되면 타이머를 무효화하는 것이 좋을 수도 있는데, 제가 깜빡 잊고 하지 않았습니다 :-)
NB: 스토리보드에 원을 추가하려면 뷰를 추가하고 선택한 후 Identity Inspector(아이덴티티 인스펙터)로 이동한 다음 Class(클래스)로 CircleClosing(원 닫기)을 지정합니다.
건배! bRo!
완료 핸들러를 원하는 경우, 이것은 Mike S가 Swift 3.0에서 수행한 것과 유사한 또 다른 솔루션입니다.
func animateCircleFull(duration: TimeInterval) {
CATransaction.begin()
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0
animation.toValue = 1
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
circleLayer.strokeEnd = 1.0
CATransaction.setCompletionBlock {
print("animation complete")
}
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
CATransaction.commit()
}
완료 핸들러를 사용하면 동일한 기능을 재귀적으로 호출하여 애니메이션을 다시 실행할 수 있습니다(매우 좋아 보이지 않음). 또는 조건이 충족될 때까지 연속적으로 연결되는 역함수를 사용할 수 있습니다(예:
func animate(duration: TimeInterval){
self.isAnimating = true
self.animateCircleFull(duration: 1)
}
func endAnimate(){
self.isAnimating = false
}
func animateCircleFull(duration: TimeInterval) {
if self.isAnimating{
CATransaction.begin()
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0
animation.toValue = 1
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
circleLayer.strokeEnd = 1.0
CATransaction.setCompletionBlock {
self.animateCircleEmpty(duration: duration)
}
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
CATransaction.commit()
}
}
func animateCircleEmpty(duration: TimeInterval){
if self.isAnimating{
CATransaction.begin()
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 1
animation.toValue = 0
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
circleLayer.strokeEnd = 0
CATransaction.setCompletionBlock {
self.animateCircleFull(duration: duration)
}
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
CATransaction.commit()
}
}
더 세련되게 하기 위해 다음과 같이 애니메이션의 방향을 변경할 수 있습니다.
func setCircleClockwise(){
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(M_PI * 2.0), clockwise: true)
self.circleLayer.removeFromSuperlayer()
self.circleLayer = formatCirle(circlePath: circlePath)
self.layer.addSublayer(self.circleLayer)
}
func setCircleCounterClockwise(){
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(M_PI * 2.0), clockwise: false)
self.circleLayer.removeFromSuperlayer()
self.circleLayer = formatCirle(circlePath: circlePath)
self.layer.addSublayer(self.circleLayer)
}
func formatCirle(circlePath: UIBezierPath) -> CAShapeLayer{
let circleShape = CAShapeLayer()
circleShape.path = circlePath.cgPath
circleShape.fillColor = UIColor.clear.cgColor
circleShape.strokeColor = UIColor.red.cgColor
circleShape.lineWidth = 10.0;
circleShape.strokeEnd = 0.0
return circleShape
}
func animate(duration: TimeInterval){
self.isAnimating = true
self.animateCircleFull(duration: 1)
}
func endAnimate(){
self.isAnimating = false
}
func animateCircleFull(duration: TimeInterval) {
if self.isAnimating{
CATransaction.begin()
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0
animation.toValue = 1
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
circleLayer.strokeEnd = 1.0
CATransaction.setCompletionBlock {
self.setCircleCounterClockwise()
self.animateCircleEmpty(duration: duration)
}
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
CATransaction.commit()
}
}
func animateCircleEmpty(duration: TimeInterval){
if self.isAnimating{
CATransaction.begin()
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 1
animation.toValue = 0
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
circleLayer.strokeEnd = 0
CATransaction.setCompletionBlock {
self.setCircleClockwise()
self.animateCircleFull(duration: duration)
}
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
CATransaction.commit()
}
}
스위프트 5에 대한 @Mike S의 답변 업데이트
에 효과가 있는.frame manually
、storyboard setup
、autolayout setup
class CircleView: UIView {
let circleLayer: CAShapeLayer = {
// Setup the CAShapeLayer with the path, colors, and line width
let circle = CAShapeLayer()
circle.fillColor = UIColor.clear.cgColor
circle.strokeColor = UIColor.red.cgColor
circle.lineWidth = 5.0
// Don't draw the circle initially
circle.strokeEnd = 0.0
return circle
}()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
func setup(){
backgroundColor = UIColor.clear
// Add the circleLayer to the view's layer's sublayers
layer.addSublayer(circleLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
// Use UIBezierPath as an easy way to create the CGPath for the layer.
// The path should be the entire circle.
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(Double.pi * 2.0), clockwise: true)
circleLayer.path = circlePath.cgPath
}
func animateCircle(duration t: TimeInterval) {
// We want to animate the strokeEnd property of the circleLayer
let animation = CABasicAnimation(keyPath: "strokeEnd")
// Set the animation duration appropriately
animation.duration = t
// Animate from 0 (no circle) to 1 (full circle)
animation.fromValue = 0
animation.toValue = 1
// Do a linear animation (i.e. the speed of the animation stays the same)
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
// Set the circleLayer's strokeEnd property to 1.0 now so that it's the
// right value when the animation ends.
circleLayer.strokeEnd = 1.0
// Do the actual animation
circleLayer.add(animation, forKey: "animateCircle")
}
}
용도:
의 샘플 frame manually
、storyboard setup
、autolayout setup
class ViewController: UIViewController {
@IBOutlet weak var circleV: CircleView!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func animateFrame(_ sender: UIButton) {
let diceRoll = CGFloat(Int(arc4random_uniform(7))*30)
let circleEdge = CGFloat(200)
// Create a new CircleView
let circleView = CircleView(frame: CGRect(x: 50, y: diceRoll, width: circleEdge, height: circleEdge))
view.addSubview(circleView)
// Animate the drawing of the circle over the course of 1 second
circleView.animateCircle(duration: 1.0)
}
@IBAction func animateAutolayout(_ sender: UIButton) {
let circleView = CircleView(frame: CGRect.zero)
circleView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(circleView)
circleView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
circleView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
circleView.widthAnchor.constraint(equalToConstant: 250).isActive = true
circleView.heightAnchor.constraint(equalToConstant: 250).isActive = true
// Animate the drawing of the circle over the course of 1 second
circleView.animateCircle(duration: 1.0)
}
@IBAction func animateStoryboard(_ sender: UIButton) {
// Animate the drawing of the circle over the course of 1 second
circleV.animateCircle(duration: 1.0)
}
}
사용자만 하위 분류할 수 있는 것은(는)UIView
당신은 또한 약간 더 깊이 들어갈 수 있습니다, 하위 클래스.CALayer
즉, 코어 애니메이션의 스트로크 End는 OK입니다.CALayer의 드로잉(inctx:)을 자주 호출하는 것도 좋습니다.
그리고 라운드라인 캡이 멋집니다.
핵심은 CALayer의 메서드를 재정의하는 것입니다.action(forKey:)
작업은 계층에 대한 동적 동작을 정의합니다.예를 들어 레이어의 애니메이션 가능한 속성에는 일반적으로 실제 애니메이션을 시작하는 작업 개체가 있습니다.해당 속성이 변경되면 계층은 속성 이름과 연결된 작업 개체를 찾고 이를 실행합니다.
CAShapeLayer의 내부 하위 클래스
/**
The internal subclass for CAShapeLayer.
This is the class that handles all the drawing and animation.
This class is not interacted with, instead
properties are set in UICircularRing
*/
class UICircularRingLayer: CAShapeLayer {
// MARK: Properties
@NSManaged var val: CGFloat
let ringWidth: CGFloat = 20
let startAngle = CGFloat(-90).rads
// MARK: Init
override init() {
super.init()
}
override init(layer: Any) {
guard let layer = layer as? UICircularRingLayer else { fatalError("unable to copy layer") }
super.init(layer: layer)
}
required init?(coder aDecoder: NSCoder) { return nil }
// MARK: Draw
/**
Override for custom drawing.
Draws the ring
*/
override func draw(in ctx: CGContext) {
super.draw(in: ctx)
UIGraphicsPushContext(ctx)
// Draw the rings
drawRing(in: ctx)
UIGraphicsPopContext()
}
// MARK: Animation methods
/**
Watches for changes in the val property, and setNeedsDisplay accordingly
*/
override class func needsDisplay(forKey key: String) -> Bool {
if key == "val" {
return true
} else {
return super.needsDisplay(forKey: key)
}
}
/**
Creates animation when val property is changed
*/
override func action(forKey event: String) -> CAAction? {
if event == "val"{
let animation = CABasicAnimation(keyPath: "val")
animation.fromValue = presentation()?.value(forKey: "val")
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
animation.duration = 2
return animation
} else {
return super.action(forKey: event)
}
}
/**
Draws the ring for the view.
Sets path properties according to how the user has decided to customize the view.
*/
private func drawRing(in ctx: CGContext) {
let center: CGPoint = CGPoint(x: bounds.midX, y: bounds.midY)
let radiusIn: CGFloat = (min(bounds.width, bounds.height) - ringWidth)/2
// Start drawing
let innerPath: UIBezierPath = UIBezierPath(arcCenter: center,
radius: radiusIn,
startAngle: startAngle,
endAngle: toEndAngle,
clockwise: true)
// Draw path
ctx.setLineWidth(ringWidth)
ctx.setLineJoin(.round)
ctx.setLineCap(CGLineCap.round)
ctx.setStrokeColor(UIColor.red.cgColor)
ctx.addPath(innerPath.cgPath)
ctx.drawPath(using: .stroke)
}
var toEndAngle: CGFloat {
return (val * 360.0).rads + startAngle
}
}
도움이 되는 방법
/**
A private extension to CGFloat in order to provide simple
conversion from degrees to radians, used when drawing the rings.
*/
extension CGFloat {
var rads: CGFloat { return self * CGFloat.pi / 180 }
}
내부 사용자 지정 CALayer와 함께 UIView 하위 클래스 사용
@IBDesignable open class UICircularRing: UIView {
/**
Set the ring layer to the default layer, casted as custom layer
*/
var ringLayer: UICircularRingLayer {
return layer as! UICircularRingLayer
}
/**
Overrides the default layer with the custom UICircularRingLayer class
*/
override open class var layerClass: AnyClass {
return UICircularRingLayer.self
}
/**
Override public init to setup() the layer and view
*/
override public init(frame: CGRect) {
super.init(frame: frame)
// Call the internal initializer
setup()
}
/**
Override public init to setup() the layer and view
*/
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Call the internal initializer
setup()
}
/**
This method initializes the custom CALayer to the default values
*/
func setup(){
// Helps with pixelation and blurriness on retina devices
ringLayer.contentsScale = UIScreen.main.scale
ringLayer.shouldRasterize = true
ringLayer.rasterizationScale = UIScreen.main.scale * 2
ringLayer.masksToBounds = false
backgroundColor = UIColor.clear
ringLayer.backgroundColor = UIColor.clear.cgColor
ringLayer.val = 0
}
func startAnimation() {
ringLayer.val = 1
}
}
용도:
class ViewController: UIViewController {
let progressRing = UICircularRing(frame: CGRect(x: 100, y: 100, width: 250, height: 250))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(progressRing)
}
@IBAction func animate(_ sender: UIButton) {
progressRing.startAnimation()
}
}
각도를 설정하기 위한 표시기 영상 포함
언급URL : https://stackoverflow.com/questions/26578023/animate-drawing-of-a-circle
'programing' 카테고리의 다른 글
UI 보기의 배경 이미지를 채우는 방법 (0) | 2023.08.31 |
---|---|
소프트 키보드가 나타날 때 레이아웃을 조정하는 방법 (0) | 2023.08.31 |
Oracle 데이터베이스에서 Java 저장 프로시저를 사용해야 하는 경우... 단점은 무엇입니까? (0) | 2023.08.31 |
MySQL에서 eq_ref 및 ref 유형은 무엇을 의미합니까? (0) | 2023.08.31 |
스파이피를 사용하여 2차원 보간을 수행하려면 어떻게 해야 합니까? (0) | 2023.08.31 |