ViewBuilder does not force View update

I use a ViewBuilder to generate the destination used in a NavigationSplitView (to select the detail View).

This viewBuilder depends on a parameter (in fact 2, but I try to simplify).

ViewBuilder is simple, just calls a View:

@ViewBuilder func destination(object: SomeObject, name: String) -> some View {   
    MyView(objToUse: object, nameToUse: name)
}

But this does not work. When I change the selection in the Master of the splitView, view is not updated (even though I've checked the content is updated.

This si so simple that I started using directly

    MyView(objToUse: object, nameToUse: name)

in the detail View.

It did not work either.

Now, here is the surprise: if I use a switch statement in the ViewBuilder, it works:

Let's say we have:

struct SomeContent: Hashable, Identifiable, Codable {
    var id = UUID()
    var name: String   
}
struct Object : Hashable, Identifiable, Equatable, Codable {
    var id = UUID()    
    var content: [SomeContent] = []
}

So I define a func to get all the names

func allNames(of object: SomeObject) -> [String] {
    var names : [String] = []
    
    for o in object.content {
        names.append(o.name)
    }
    return names
}

And modify ViewBuilder as follows: it works

@ViewBuilder func destination(object: SomeObject, name: String) -> some View {   
    let names : [String] = allNames(of: object)

    switch name {
        case names[0]: MyView(objToUse: object, nameToUse: name)
            
        case names[1]: MyView(objToUse: object, nameToUse: name)
            
        case names[2]: MyView(objToUse: object, nameToUse: name)
            
        default:   EmptyView()
    }

It also works with nested if else if instead of a switch.

What is it I am missing ?

Replies

objectToUse and nameToUse of MyView should be a Bindable<Object> and Bindable<String> parameters to a pair of matching local variables, so when a data change occurs, it will trigger a UI update. You should also use return in each case.

Thanks, that's the root cause.

In my case, how would I use it in ViewBuilder ?

I also have issues as I have an init(object: SomeObject, name: String) in the class and struggle to initialize the bindings…