我正尝试在视图顶部添加一个计时器,以显示该视图已打开多长时间。
到目前为止,我得到的是:
@State var isTimerRunning = false
@State private var startTime = Date()
@State private var timerString = "0:0"
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
Text(self.timerString)
.font(Font.system(.largeTitle, design: .monospaced))
.onReceive(timer) { _ in
if self.isTimerRunning {
timerString = String(format: "%.2f", (Date().timeIntervalSince( self.startTime)))
}
}
.onAppear() {
if !isTimerRunning {
timerString = "0:0"
startTime = Date()
}
isTimerRunning.toggle()
}然而,它以"1.32434234234234“的形式显示毫秒和秒,而我希望它以"12:43”的形式显示秒和分钟。
发布于 2021-01-16 00:21:28
为此,您可以使用TimeInterval的扩展。通过更改formatter.unitsStyle (.positional将显示00:00:00,而.abbreviated将显示0h 0m 0s)和formatter.zeroFormattingBehavior变量,您可以很好地定制字符串。
extension found here的演职人员。
extension TimeInterval {
func format(using units: NSCalendar.Unit) -> String {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = units
formatter.unitsStyle = .positional
formatter.zeroFormattingBehavior = .pad
return formatter.string(from: self) ?? ""
}
}
struct TimerPlayground: View {
@State var isTimerRunning = false
@State private var startTime = Date()
@State var interval = TimeInterval()
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
Text(interval.format(using: [.hour, .minute, .second]))
.font(Font.system(.largeTitle, design: .monospaced))
.onReceive(timer) { _ in
if self.isTimerRunning {
interval = Date().timeIntervalSince(startTime)
}
}
.onAppear() {
if !isTimerRunning {
startTime = Date()
}
isTimerRunning.toggle()
}
}
}
struct TimerPlayground_Previews: PreviewProvider {
static var previews: some View {
TimerPlayground()
}
}根据@Duncan C的评论,这里是一个更新版本,它只创建一次格式化程序(本地),以获得更好的性能。
struct TimerPlayground: View {
@State var isTimerRunning = false
@State private var startTime = Date()
@State var interval = TimeInterval()
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State var formatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second]
formatter.unitsStyle = .abbreviated
formatter.zeroFormattingBehavior = .pad
return formatter
}()
var body: some View {
Text(formatter.string(from: interval) ?? "")
.font(Font.system(.largeTitle, design: .monospaced))
.onReceive(timer) { _ in
if self.isTimerRunning {
interval = Date().timeIntervalSince(startTime)
}
}
.onAppear() {
if !isTimerRunning {
startTime = Date()
}
isTimerRunning.toggle()
}
}
}发布于 2021-01-16 00:09:02
使用dateComponents获取开始时间和当前时间之间的差值。
extension Date {
func passedTime(from date: Date) -> String {
let difference = Calendar.current.dateComponents([.minute, .second], from: date, to: self)
let strMin = String(format: "%02d", difference.minute ?? 00)
let strSec = String(format: "%02d", difference.second ?? 00)
return "\(strMin):\(strSec)"
}
}在视图中
struct ContentView: View {
@State private var isTimerRunning = false
@State private var startTime = Date()
@State private var timerString = "00:00"
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
Text(self.timerString)
.font(Font.system(.largeTitle, design: .monospaced))
.onReceive(timer) { _ in
if self.isTimerRunning {
timerString = Date().passedTime(from: startTime)
}
}
.onAppear() {
if !isTimerRunning {
timerString = "0:0"
startTime = Date()
}
isTimerRunning.toggle()
}
}
}https://stackoverflow.com/questions/65739258
复制相似问题