簡體   English   中英

相對於彼此將多個asyncAfter排隊-Swift 3

[英]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秒?

有兩種可能:

  1. 如果真的放慢了速度,那么每次都可能沿着整個路徑行駛。 因此,后面的筆划有更多的借鑒意義,並且需要更多的時間。 因此,渲染速度較慢。

    您可以通過定期拍攝屏幕快照,然后渲染先前的屏幕快照以及新路徑來解決此問題。 這樣一來,您的路徑就受到了限制。

  2. 還要注意,它可能不會變慢,而只是將計時器合並在一起(如果將來有大量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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM