Ios UITextView在循环期间不更新
因此,我尝试了两种不同的方式在屏幕上显示计时器倒计时 代码将打印到控制台,但不会打印到UITextView(在两种循环情况下)。在重复中,UITextView以0结尾,这是它显示的唯一内容,而不是原始txt“时间计数”。。。。在实现注释循环的情况下,UITextView仅显示1(倒计时结束)。。。尽管这些命令与UITextView位于同一个括号中,但为什么要打印到控制台上,并且它们会重复 运行代码并单击“软”后显示图像(这是应用程序brewery egg timer的衍生产品)Ios UITextView在循环期间不更新,ios,swift,loops,uitextview,Ios,Swift,Loops,Uitextview,因此,我尝试了两种不同的方式在屏幕上显示计时器倒计时 代码将打印到控制台,但不会打印到UITextView(在两种循环情况下)。在重复中,UITextView以0结尾,这是它显示的唯一内容,而不是原始txt“时间计数”。。。。在实现注释循环的情况下,UITextView仅显示1(倒计时结束)。。。尽管这些命令与UITextView位于同一个括号中,但为什么要打印到控制台上,并且它们会重复 运行代码并单击“软”后显示图像(这是应用程序brewery egg timer的衍生产品) 您从未(嗯,几
您从未(嗯,几乎从未)想要使用
sleep()
文本未更新的原因是,您正在运行从不允许UIKit更新视图的闭环
相反,您要做的是使用间隔为1秒的重复计时器。每次定时器启动时,减小计数器并更新UI。当计数器达到零时,停止计时器
下面是一个简单的例子:
import UIKit
let softTime = 5
let medTime = 7
let hardTime = 12
class ViewController: UIViewController {
@IBOutlet weak var timerTextView: UITextView!
var theTimer: Timer?
@IBAction func eggHardnessButton(_ sender: UIButton) {
let hardness = sender.currentTitle
var numSeconds = 0
// set number of seconds based on button title
switch hardness {
case "Soft":
numSeconds = softTime * 60
case "Medium":
numSeconds = medTime * 60
case "Hard":
numSeconds = hardTime * 60
default:
// some other button called this func, so just return
return()
}
// stop current timer if it's running
if let t = theTimer {
if t.isValid {
t.invalidate()
}
}
// update text field with selected time
let timeWord = String(numSeconds)
self.timerTextView.text = timeWord
// start a timer with 1-second interval
theTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
numSeconds -= 1
let timeWord = String(numSeconds)
self.timerTextView.text = timeWord
// if we've reached Zero seconds remaining
if numSeconds == 0 {
// stop the timer
timer.invalidate()
}
}
}
}
有几点:
- 当你的应用程序改变用户界面时,这些改变实际上并没有得到响应
渲染到屏幕,直到代码返回并访问应用程序的
事件循环。因此,在重复循环中,将不会显示任何内容
直到循环完成,用户界面才会停止
- 不要在主线程上使用sleep()。这会阻碍一切,而且
你的应用程序突然停止
- 如果要每秒更新一次UI,请设置一个重复计时器
每秒触发一次,并在计时器代码中更新UI
sleep
停止当前线程。它将无法按照您编写的方式更新UI。如果你想使用计时器,你可以直接使用。我建议你不要使用睡眠。。。这门课真的做到了吗?我在前一段时间拍的,但是忘记了定时器在主线程上执行它的块?只是想知道UI更新。@Flander-来自苹果的文档:创建一个计时器,并以默认模式在当前运行循环中安排它。
。。。因此,在本例中,如果在主线程上调用eggHardnessButton()
func(例如响应.touchupinder
),则计时器在主线程上运行。我读到@DonMag,但不确定默认模式下的运行循环是否意味着在主线程上运行。谢谢你的澄清。
import UIKit
let softTime = 5
let medTime = 7
let hardTime = 12
class ViewController: UIViewController {
@IBOutlet weak var timerTextView: UITextView!
var theTimer: Timer?
@IBAction func eggHardnessButton(_ sender: UIButton) {
let hardness = sender.currentTitle
var numSeconds = 0
// set number of seconds based on button title
switch hardness {
case "Soft":
numSeconds = softTime * 60
case "Medium":
numSeconds = medTime * 60
case "Hard":
numSeconds = hardTime * 60
default:
// some other button called this func, so just return
return()
}
// stop current timer if it's running
if let t = theTimer {
if t.isValid {
t.invalidate()
}
}
// update text field with selected time
let timeWord = String(numSeconds)
self.timerTextView.text = timeWord
// start a timer with 1-second interval
theTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
numSeconds -= 1
let timeWord = String(numSeconds)
self.timerTextView.text = timeWord
// if we've reached Zero seconds remaining
if numSeconds == 0 {
// stop the timer
timer.invalidate()
}
}
}
}