[英]Queue multiple asyncAfter relative to eachother - Swift 3
我正在嘗試將UITouch事件中記錄的一系列點重播到我的繪圖處理程序中。 我希望每個點在最后一個點之后0.1秒繪制一次。 一旦有了CGPoints數組,我便會遍歷該數組並將GDC dispatchAfter排隊,以使用該點調用我的draw方法。
override func replay(_ queue: DispatchQueue) {
isReplaying = true
for stroke in strokeHistory {
var additionalTime = 0.0
for curPoint in stroke.points {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + additionalTime, execute: {
[unowned self, s = stroke, lrp = stroke.lastReplayPoint] in
s.lastReplayPoint = lrp
switch curPoint.state {
case .began:
self.strokeBegan(s, atPoint: curPoint)
case .changed:
self.strokeMoved(s, toPoint: curPoint)
case .ended:
self.strokeEnded(s, atPoint: curPoint)
default :
NSLog("Point phase default.")
}
})
additionalTime = additionalTime + 0.1
stroke.lastReplayPoint = curPoint
}
}
}
播放有效,但逐漸變慢,並以越來越慢的間隔繪制大量的點。 如何將這些點排隊,以在它們之間繪制0.1秒?
有兩種可能:
如果真的放慢了速度,那么每次都可能沿着整個路徑行駛。 因此,后面的筆划有更多的借鑒意義,並且需要更多的時間。 因此,渲染速度較慢。
您可以通過定期拍攝屏幕快照,然后渲染先前的屏幕快照以及新路徑來解決此問題。 這樣一來,您的路徑就受到了限制。
還要注意,它可能不會變慢,而只是將計時器合並在一起(如果將來有大量asyncAfter
調用,就會發生這種情況)。 合並時,總體速度應基本保持一致,但將它們合並在一起,可以使您的計時器更加結結巴巴。
您可以使用重復計時器(不會將它們合並在一起)來解決此問題。 或者,如果您創建一個一次性計時器,則可以指定DispatchSource.TimerFlag.strict
以選擇退出合並。
但是,更容易的是,您可以使用Core Animation為筆觸設置動畫,從而完全避免此問題。 它不僅不會因為后一點的渲染速度變慢,而且更加容易並且渲染出更加流暢的動畫。 例如,如果您為CAShapeLayer
指定了path
:
let path: UIBezierPath = ... // construct your path any way you want
let pathLayer = CAShapeLayer()
pathLayer.strokeColor = UIColor.blue.cgColor
pathLayer.fillColor = UIColor.clear.cgColor
pathLayer.lineWidth = 3
view.layer.addSublayer(pathLayer)
然后,您可以為該路徑的筆觸設置動畫,如下所示:
let stroke = CABasicAnimation(keyPath: "strokeEnd")
stroke.fromValue = 0.0
stroke.duration = 1.0 // change this as you see fit, perhaps saving the original time it took to capture the path and using that (or some fraction thereof) when animating the path
pathLayer.add(stroke, forKey: nil)
產生的路徑為7,200點:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.