Related to forcing an update, I would like SwiftUI to reload and update my content view when a DateFormatter instance's format property changes.
Example:
private extension String {
enum TimeDateFormat: String {
case civilian = "hh:mm a"
case military = "HH:mm"
init(is12h: Bool) {
self = is12h ? .civilian : .military
}
}
}
struct ContentView: View {
private let formatter = DateFormatter()
@State private var is24h: Bool = false
var body: some View {
Text(formatter.string(from: .now))
Button {
is24h.toggle()
formatter.dateFormat = .TimeDateFormat(is12h: !is24h).rawValue
// DOESN'T UPDATE THE VIEW
} label: {
Text("Toggle format")
}
}
init() {
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = .TimeDateFormat.civilian.rawValue
}
}
I have tried using Text(Date.now, formatter: formatter) and that not only does not update the format, Text(_:formatter:) does not even apply the format I set in the ContentView initializer.
I have also tried reversing the order of the instance property setters.
// ...
formatter.dateFormat = .TimeDateFormat(is12h: is24h).rawValue
is24h.toggle()
// DOESN'T UPDATE THE VIEW
The following code works. However, this code introduces a third instance variable, something I specficaly would like to avoid.
struct ContentView: View {
private let formatter = DateFormatter()
@State private var is24h: Bool = false
@State private var text: String
var body: some View {
Text(text)
Button {
is24h.toggle()
formatter.dateFormat = .TimeDateFormat(is12h: !is24h).rawValue
text = formatter.string(from: .now)
} label: {
Text("Toggle format")
}
}
init() {
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = .TimeDateFormat.civilian.rawValue
text = formatter.string(from: .now)
}
}
Is there a solution to reload the view without introducing a third variable?
It can be done as follow: