onChange 快速更新变量,永远循环

问题描述 投票:0回答:2

我陷入了以下问题,我在 Hstack 中创建了 2 个文本字段,用户可以在其中以 HH:mm 格式插入本地时间,并在第二个文本字段中自动转换为 UTC 时间,反之亦然。 为此,我使用了 onchange 方法,当变量“localTime”更改时,它会更新变量“utcTime”,反之亦然,但是当我运行代码时,它会进入无限循环,因为它们不断相互更新......任何解决方案如何避免这种情况?

import SwiftUI

struct TimeView: View {
    @Binding var localDate : Date?
    @Binding var utcDate : Date?
    
    /// continete l'ora in formato HH:mm
    @Binding var localTime : String
    @Binding var utcTime : String
    
    @Binding var selectedDate: Date
    
    @State var shouldUpdateUTCTime = true
    @State var shouldUpdateLocalTime = true
   
    let dateTimeFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm"
        formatter.timeZone = TimeZone(identifier: "UTC")
        return formatter
    }()
    
    @FocusState var isFocused: Bool

    var body: some View {
        HStack {
            TimeTextField(time: $localTime, description: "Local Time")
                .multilineTextAlignment(.center)
                .keyboardType(.numbersAndPunctuation)
                .onChange(of: localTime) { oldValue, newValue in
                    if shouldUpdateUTCTime {
                        updateUTCTime()
                    }
                }
                
            
            TimeTextField(time: $utcTime, description: "UTC")
                .multilineTextAlignment(.center)
                .keyboardType(.numbersAndPunctuation)
                .onChange(of: utcTime) { oldValue, newValue in
                      if shouldUpdateLocalTime {
                        updateLocalTime()
                    }
                  
                }
                
        }
    }
    
    func updateUTCTime() {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "HH:mm"
        if let utcDate = dateFormatter.date(from: localTime) {
            dateFormatter.timeZone = TimeZone(identifier: "UTC") // convert to utc the local
            let utcDateString = dateTimeFormatter.string(from: utcDate)
            utcTime = utcDateString
        }
    }
    func updateLocalTime() {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "HH:mm"
        if let local = dateFormatter.date(from: utcTime) {
            dateFormatter.timeZone = TimeZone.current // convert to current the local
            let localDateString = dateTimeFormatter.string(from: local)
            localTime = localDateString
        }
    }

}


swift date swiftui logic
2个回答
1
投票
enum Field: Hashable {
    case universalTime
    case localTime
}

@FocusState var focusedState: Field?

使用 focusState,向每个文本字段添加焦点修饰符,如下所示:

TextField("", text: $localTime)
     .focused($focusedState, equals: .localTime)

TextField("", text: $universalTime)
     .focused($focusedState, equals: .universalTime)

然后 .onChange 修饰符检查 focusState 并根据当前/活动 focusState 调用方法,

对于当地时间文本字段:

.onChange(of: localTime) { _ in
  if focusedState == .localTime {
      updateUTCTime()
     }
  }

对于通用时间文本字段:

.onChange(of: universalTime) { _ in
   if focusedState == .universalTime {
       updateLocalTime()
     }
   }

现在就不会进入无限循环了。


0
投票

您是否尝试过像布尔值一样设置其他值?当其中一个的 onChange 为 true 时将其设置为 true,而另一个的 onChange 为 false 时将其设置为 true,并且仅当其为 false 时才对设置做出反应。我认为就像两个布尔值,在每个函数中为其他函数设置时间,一个设置为 true,一个设置为 false。仅当设置 other 时才应设置为 true,例如如果不是布尔值,则将设置 other 设置为 true 并设置 other。

之后将此布尔值设置为 false。变量应该是全局的,这两个布尔值,并且可以被两个函数访问。操作顺序应该是 if !(other 设置 this) then set setting other to true then set other, 毕竟,在函数中将 other 设置为 false。我不知道你在哪里设置这些变量、布尔值,你只是拥有它们。

由于这不起作用,您可以尝试在setter方法中进行其他检查,在设置之前其他是否已经正确,X E。

© www.soinside.com 2019 - 2024. All rights reserved.