Anyone know if SwiftUI support ternary conditionals? I have a text view with conditional argument (Text(badgeCount == nil ? " " :"\(badgeCount!)")) that displays an empty view. Surprisingly, it works if I remove the @State attribute from the view.
import SwiftUI
struct RedBadgeView: View {
@State var badgeCount: Int?
init (_ badgeCount: Int? = nil) {
self.badgeCount = badgeCount
}
var body: some View {
// Something about this Syntax is throwing off SwiftUI.
Text(badgeCount == nil ? " " :"\(badgeCount!)")
}
}
struct RedBadgeView_Previews: PreviewProvider {
static var previews: some View {
RedBadgeView(1)
}
}
3 Answers 3
There's no need to use the ternary operator here at all. Moreover, doing a nil check and then force unwrapping in a ternary operator is a bad idea.
Instead, you should use optional chaining to access the description of badgeCount and provide the " " as a default value.
Text(badgeCount?.description ?? " ")
However, your problem of the view not updating is coming from the fact that you never initialise your State, you just assign a value to its wrapped value. To access the state, you need to use the _ prefix before the variable name.
init (_ badgeCount: Int? = nil) {
self._badgeCount = State(initialValue: badgeCount)
}
Comments
Sure ternary conditions work. However you initialization of the State is wrong. You are initializing a regular Int.
init (_ badgeCount: Int? = nil) {
self.badgeCount = badgeCount // >> If you initializing an Int
self._badgeCount = State(initialValue: badgeCount) // >> If you initializing a State variable
}
Hence, everything will work with State aswell:
struct ContentView: View {
@State var badgeCount: Int?
init (_ badgeCount: Int? = nil) {
self._badgeCount = State(initialValue: badgeCount)
}
var body: some View {
Text(badgeCount == nil ? " " :"\(badgeCount!)")
}
}
Comments
In addition to other answers, if you're using SwiftUI 2 you can do it in more swifty way which is to use if-let directly in the body:
var body: some View {
if let badgeCount = badgeCount {
Text(badgeCount)
}
}
If badgeCount is nil, the body will return an EmptyView. However, you may return some other view as well:
@ViewBuilder
var body: some View {
if let badgeCount = badgeCount {
Text(badgeCount)
} else {
Text(" ")
}
}
(First you need to init/assign a value to badgeCount to see the view).