当UIView的背景颜色应该改变颜色时,我有一些时间。该数组保存0-10000ms的值,其中每个索引是第一次更改和当前更改之间的持续时间。我已经实现了一个循环来在预定的时间执行任务,并且使用print语句,它似乎正在工作。但是,背景颜色仅更改为最后一种颜色,而不是连续更改。
我相信这是因为在循环完成之前,背景颜色不会更新。这是否正确,如果是,我该如何解决这个问题?
sendingView.backgroundColor = UIColor.black
let startingTime = getCurrentMillis()
var found = false
for time in receivingMsgData {
while(!found) {
let curDuration = getCurrentMillis() - startingTime
if curDuration > time {
if(sendingView.backgroundColor == UIColor.black) {
sendingView.backgroundColor = UIColor.white
print("playing at \(getCurrentMillis()-startingTime) turning white")
} else {
sendingView.backgroundColor = UIColor.black
print("playing at \(getCurrentMillis()-startingTime) turning black")
}
found = true
}
}
found = false
}
答案 0 :(得分:2)
尝试这样的事情
DispatchQueue.global(qos: .userInitiated).async {
let delay:TimeInterval = 0.01 // Seconds
for index in 0..<100 {
if index % 2 == 0 {
Thread.sleep(forTimeInterval: delay)
DispatchQueue.main.async {
self.view.backgroundColor = UIColor.white
print("white")
}
}else{
Thread.sleep(forTimeInterval: delay)
DispatchQueue.main.async {
self.view.backgroundColor = UIColor.black
print("black")
}
}
}
}
在异步线程中执行操作并更改主线程上的颜色 你在主线程中做了很多事情导致它挂起,同时放一些延迟,以便用户可以查看动画
在你的案例中尝试这样的事情
let delay:TimeInterval = 0.01 // Seconds
sendingView.backgroundColor = UIColor.black
let startingTime = getCurrentMillis()
var found = false
DispatchQueue.global(qos: .userInitiated).async {
for time in receivingMsgData {
while(!found) {
let curDuration = getCurrentMillis() - startingTime
if curDuration > time {
if(sendingView.backgroundColor == UIColor.black) {
Thread.sleep(forTimeInterval: delay)
DispatchQueue.main.async {
sendingView.backgroundColor = UIColor.white
print("playing at \(getCurrentMillis()-startingTime) turning white")
}
} else {
Thread.sleep(forTimeInterval: delay)
DispatchQueue.main.async {
sendingView.backgroundColor = UIColor.black
print("playing at \(getCurrentMillis()-startingTime) turning black")
}
}
found = true
}
}
found = false
}
}
答案 1 :(得分:1)
您设置颜色时,您发布的代码会阻止主线程或操作不在主线程上。在完成整个循环的执行或经过一段时间之后,这两种情况很可能不会导致任何变化。
当您处理某些时间安排的数据时,可能与屏幕更新的速度无关,您需要在屏幕刷新时按需提供颜色。
在您的情况下,我建议使用显示链接CADisplayLink
,该链接用于在屏幕刷新时触发。您甚至可以从显示链接本身开始获取当前时间值。经过的时间可以与您在代码中使用curDuration
的方式相同。假设代码的其余部分正常工作。
答案 2 :(得分:0)
我相信这是因为在循环完成之前,背景颜色不会更新。这是正确的
是的,确实如此。直到主线程上的所有代码完成并且提交了CATransaction之后才会进行绘图。你需要做两件事之一:
在后台线程上运行耗时的代码,进入主线程只与界面通信并设置颜色。
使用某种形式的延迟来延长主线程的时间,以便在继续“循环”之前进行绘图。