Hob*_*ist 1 multithreading uiprogressview ios swift
我正在尝试让进度条充当计时器并从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)
}
Run Code Online (Sandbox Code Playgroud)
print()打印正确的结果,但进度条永远不会更新,有时它会在12-15%左右完成一次更新,只有JUMP然后再做其他事情.
如何使此栏稳定地向下流动,然后在计时器结束时执行任务而不阻止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()
}
Run Code Online (Sandbox Code Playgroud)
或者,如果你在后台线程上做某事想要发布更新UIProgressView比主线程可以更快地发布更新,那么我会使用类型的调度源将它发布到主线程DISPATCH_SOURCE_TYPE_DATA_ADD.
但是,如果您只是尝试在一段固定的时间内更新进度视图,则显示链接可能比计时器更好.
| 归档时间: |
|
| 查看次数: |
2205 次 |
| 最近记录: |