[英]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.