Ios Swift-计划计时器秒表时间部分不工作
请放心,我一周前学会了Swift和Xcode(我正在创建一个应用程序,以便在假期学习Swift) 我使用scheduledTimer创建了一个计时器作为秒表。秒和分都很好,但我没时间工作。我做错了什么Ios Swift-计划计时器秒表时间部分不工作,ios,swift,nstimer,Ios,Swift,Nstimer,请放心,我一周前学会了Swift和Xcode(我正在创建一个应用程序,以便在假期学习Swift) 我使用scheduledTimer创建了一个计时器作为秒表。秒和分都很好,但我没时间工作。我做错了什么 currentTime = 0 timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in self.currentTime += 1 let hoursPortion = String(f
currentTime = 0
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
self.currentTime += 1
let hoursPortion = String(format: "%02d", CGFloat(self.currentTime) * 60)
let minutesPortion = String(format: "%02d", self.currentTime / 60)
let secondsPortion = String(format: "%02d", self.currentTime % 60)
//let tenPortion = String(format: "%d", self.currentTime * 10 % 10)
self.TimerDisplay.text = "\(hoursPortion):\(minutesPortion):\(secondsPortion)"
}
这不是最好的方法,因为计时器不能保证足够准确,它会随时间漂移。更好的方法是记录开始时间,并使用日历功能为您提供经过的时间。e、 g
let startTime = Date()
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
let now = Date()
let components = Calendar.current.dateComponents([.hour, .minute, .second], from: startTime, to: now)
guard let hoursPortion = components.hour, let minutesPortion = components.minute, let secondsPortion = components.second
else {
preconditionFailure("Should not happen")
}
self.TimerDisplay.text = "\(hoursPortion):\(minutesPortion):\(secondsPortion)"
}
这不是最好的方法,因为计时器不能保证足够准确,它会随时间漂移。更好的方法是记录开始时间,并使用日历功能为您提供经过的时间。e、 g
let startTime = Date()
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
let now = Date()
let components = Calendar.current.dateComponents([.hour, .minute, .second], from: startTime, to: now)
guard let hoursPortion = components.hour, let minutesPortion = components.minute, let secondsPortion = components.second
else {
preconditionFailure("Should not happen")
}
self.TimerDisplay.text = "\(hoursPortion):\(minutesPortion):\(secondsPortion)"
}
正如其他人所说,你不应该自己去记录时间。让系统计算出经过了多少时间。我也倾向于为您设置字符串格式:
@IBOutlet weak var elapsedLabel: UILabel!
weak var timer: Timer?
private var formatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
formatter.allowedUnits = [.hour, .minute, .second]
formatter.zeroFormattingBehavior = .pad
return formatter
}()
private func startTimer() {
timer?.invalidate() // stop prior timer, if any
let startTime = Date()
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
self?.elapsedLabel.text = self?.formatter.string(from: startTime, to: Date())
}
}
deinit {
timer?.invalidate()
}
顺便说一句,这是一个微妙的点,但请注意在
计时器的捕获列表中使用了[弱自我]
。如果没有这一点,则会出现强引用循环的变化,因为计时器在使其无效之前不会停止,但在解决计时器对视图控制器的强引用之前,无法调用视图控制器的deinit
。通过在闭包中使用[weak self]
捕获列表,我们打破了这个循环,允许在视图控制器被解除时释放它,它将为您停止计时器。正如其他人所说,您不应该自己跟踪时间。让系统计算出经过了多少时间。我也倾向于为您设置字符串格式:
@IBOutlet weak var elapsedLabel: UILabel!
weak var timer: Timer?
private var formatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
formatter.allowedUnits = [.hour, .minute, .second]
formatter.zeroFormattingBehavior = .pad
return formatter
}()
private func startTimer() {
timer?.invalidate() // stop prior timer, if any
let startTime = Date()
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
self?.elapsedLabel.text = self?.formatter.string(from: startTime, to: Date())
}
}
deinit {
timer?.invalidate()
}
顺便说一句,这是一个微妙的点,但请注意在计时器的捕获列表中使用了[弱自我]
。如果没有这一点,则会出现强引用循环的变化,因为计时器在使其无效之前不会停止,但在解决计时器对视图控制器的强引用之前,无法调用视图控制器的deinit
。通过在闭包中使用[弱自我]
捕获列表,我们打破了这个循环,允许在视图控制器被解除时释放它,它将为您停止计时器。如果当前时间已过秒,则小时数为currentTime/3600
。我不知道你为什么要乘以20。无论如何,这种方法可能不是最好的;计时器不准确。更好的方法是在秒表启动时创建一个日期
,并计算该日期与计时器计时时的“现在”之间的差值DateComponents
可以帮助您从日期获取字段。是的,这是真的,20应该是3600,但我将其设置为20,这样我就不必等待一个小时来查看它是否有效。我将HoursPart设置为乘法,因为我认为1小时=3600秒。不,你想除法,因为1小时=3600秒;如果currentTime
=3600,则为1小时,因此currentTime/3600
如果当前时间已过秒,则小时为currentTime/3600
。我不知道你为什么要乘以20。无论如何,这种方法可能不是最好的;计时器不准确。更好的方法是在秒表启动时创建一个日期
,并计算该日期与计时器计时时的“现在”之间的差值DateComponents
可以帮助您从日期获取字段。是的,这是真的,20应该是3600,但我将其设置为20,这样我就不必等待一个小时来查看它是否有效。我将HoursPart设置为乘法,因为我认为1小时=3600秒。不,你想除法,因为1小时=3600秒;如果currentTime
=3600,则这是1小时,因此currentTime/3600
感谢您的宝贵意见!我并没有在我正在做的项目中使用它,但我正在测试一些东西,并让它开始工作。如何设置计时器的格式,使其显示00:02:20,持续2分20秒?请使用您在初始问题中使用的字符串(格式:)方法,或使用Rob提供的DateComponents格式建议。感谢您的宝贵意见!我并没有在我正在做的项目中使用它,但我正在测试一些东西,并让它开始工作。如何设置计时器的格式,使其显示00:02:20,持续2分20秒?使用您在初始问题中使用的字符串(格式:)方法,或使用Rob提供的DateComponents格式建议。