A resposta de Mike é ótima! Outra maneira simples e agradável de fazer isso é usar drawRect combinado com setNeedsDisplay (). Parece lento, mas não é :-)
Queremos desenhar um círculo começando do topo, que é -90 ° e termina em 270 °. O centro do círculo é (centerX, centerY), com um determinado raio. CurrentAngle é o ângulo atual do ponto final do círculo, indo de minAngle (-90) a 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
Em drawRect, especificamos como o círculo deve ser exibido:
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)
}
O problema é que agora, como currentAngle não está mudando, o círculo é estático, e nem mesmo é mostrado, como currentAngle = minAngle.
Em seguida, criamos um cronômetro e, sempre que esse cronômetro dispara, aumentamos o currentAngle. No início da classe, adicione o tempo entre dois incêndios:
let timeBetweenDraw:CFTimeInterval = 0.01
Em seu init, adicione o cronômetro:
NSTimer.scheduledTimerWithTimeInterval(timeBetweenDraw, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
Podemos adicionar a função que será chamada quando o cronômetro disparar:
func updateTimer() {
if currentAngle < maxAngle {
currentAngle += 1
}
}
Infelizmente, ao executar o aplicativo, nada é exibido porque não especificamos o sistema para que ele desenhe novamente. Isso é feito chamando setNeedsDisplay (). Aqui está a função de cronômetro atualizada:
func updateTimer() {
if currentAngle < maxAngle {
currentAngle += 1
setNeedsDisplay()
}
}
_ _ _
Todo o código de que você precisa está resumido aqui:
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)
}
}
Se você quiser alterar a velocidade, basta modificar a função updateTimer, ou a taxa em que esta função é chamada. Além disso, você pode querer invalidar o cronômetro quando o círculo estiver completo, o que eu esqueci de fazer :-)
NB: Para adicionar o círculo em seu storyboard, basta adicionar uma visualização, selecioná-la, ir para o Inspetor de identidade e, como Classe , especificar CircleClosing .
Felicidades! Mano