簡體   English   中英

從分派更新時,UIProgressView不會更新進度

[英]UIProgressView won't update progress when updated from a dispatch

我正在嘗試使進度條充當計時器,並從15秒開始倒計時,這是我的代碼:

private var timer: dispatch_source_t!
private var timeRemaining: Double = 15

override public func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    profilePicture.layer.cornerRadius = profilePicture.bounds.width / 2

    let queue = dispatch_queue_create("buzz.qualify.client.timer", nil)
    timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue)
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 10 * NSEC_PER_MSEC, 5 * NSEC_PER_MSEC)
    dispatch_source_set_event_handler(timer) {
        self.timeRemaining -= 0.01;
        self.timerBar.setProgress(Float(self.timeRemaining) / 15.0, animated: true)
        print(String(self.timerBar.progress))
    }
    dispatch_resume(timer)
}

print()打印出正確的結果,但是進度條永遠不會更新,有時它會以大約12%至15%的完整速度執行一次單獨更新,然后在那里跳轉,然后什么也不做。

如何使此欄穩定下來,然后在計時器結束時執行任務而不阻塞UI線程。

在siburb的回答中,他正確地指出應確保UI更新在主線程上進行。

但是我有一個次要的觀察,就是說您每秒執行100次更新,並且這樣做沒有意義,因為最大的屏幕刷新率為每秒60幀。

但是,顯示鏈接類似於計時器,只是它鏈接到屏幕刷新率。 您可以執行以下操作:

var displayLink: CADisplayLink?
var startTime: CFAbsoluteTime?
let duration = 15.0

func startDisplayLink() {
    startTime = CFAbsoluteTimeGetCurrent()
    displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:")
    displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
}

func stopDisplayLink() {
    displayLink?.invalidate()
    displayLink = nil
}

func handleDisplayLink(displayLink: CADisplayLink) {
    let percentComplete = Float((CFAbsoluteTimeGetCurrent() - startTime!) / duration)
    if percentComplete < 1.0 {
        self.timerBar.setProgress(1.0 - percentComplete, animated: false)
    } else {
        stopDisplayLink()
        self.timerBar.setProgress(0.0, animated: false)
    }
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    startDisplayLink()
}

另外,如果您要在后台線程上執行某些操作,以將更新發布到UIProgressView速度快於主線程可以UIProgressView提供服務的速度,那么我將使用DISPATCH_SOURCE_TYPE_DATA_ADD類型的派發源將更新發布到主線程。

但是,如果您只是嘗試在某個固定的時間段內更新進度視圖,則顯示鏈接可能比計時器更好。

您必須始終在主線程上更新UI。 我不是Swift專家,但您似乎正在嘗試在后台更新UIProgressView

嘗試像這樣在主隊列上更新UIProgressView

dispatch_async(dispatch_get_main_queue(),^{
    self.timerBar.setProgress(Float(self.timeRemaining) / 15.0, animated: true)
    print(String(self.timerBar.progress))
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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