swiftswiftuiswift-optionals

Avoid repeated views when checking optionals in SwiftUI


I currently have this code:

if let isSaved = vm.place?.isSaved {
    Text(isSaved ? "Saved" : "Want to go")
} else {
    Text("Want to go")
}

How can I rewrite this to avoid having to essentially use the "Want to go" version of the Text view twice?

If I try just:

Text(vm.place?.isSaved ? "Saved" : "Want to go")

I get the error:

Value of optional type 'Bool?' must be unwrapped to a value of type 'Bool'


Solution

  • In fact, vm.place?.isSaved returns Optional<Bool> which has 3 cases:

    .none
    .some(true)
    .some(false)
    

    Thats the reason you cant use the ternary operator directly.

    You can get rid of the optionality by ignoring a case like:

    Text(vm.place?.isSaved == true ? "Saved" : "Want to go")
    

    or by giving it a default value like:

    Text(vm.place?.isSaved ?? false ? "Saved" : "Want to go")
    

    Maybe separating the code a bit helps it to be more clear:

    let optionalIsSaved: Optional<Bool> = vm.place?.isSaved
    let defaultedIsSaved: Bool = optionalIsSaved ?? false
    Text(defaultedIsSaved ? "Saved" : "Want to go")