0

Problem

XCode 15 Beta

I'm testing the new Beta version of Xcode and had some problems with the @Binding behavior.

I recreated the approximate view structure. I tried accessing the models array of the Model1 in the second view. Im using the textfield onEditingChanged to display a new view below when something is searched. But when I first tap on the textfield the vm.model1Selection gets set to nil and the vm.selectedModel1 needs to be reselected through a menu. Then on the second try everything works. I tried a lot restructuring the code but the problem stays the same.

During my attempts to fix the problem, I think the problem lies in the following snippet:

if !selectedDepot.securities.isEmpty {

Edit:

I think the main problem is that the values of the variables inside the viewModel get restetted

Code:

Models

@Model
final class Model1 {
    @Attribute(.unique) var id: UUID
    var name: String
    
    @Relationship(.cascade, inverse: \Model2.model1)
    var models: [Model2] = []
    
    init(name: String) {
        self.id = UUID()
        self.name = name
    }
}

@Model
final class Model2 {
    @Attribute(.unique) var id: UUID
    var name: String
    var model1: Model1?
    
    init(name: String) {
        self.id = UUID()
        self.name = name
    }
}

View Model

I've created this ViewModel with the new @Observable feature.

@Observable
class ViewModel {
var model1Selection: Model1? = nil
var model2Selection: Model2? = nil
}

Views

struct ParentView: View {
@Bindable var vm = ViewModel()
@Query(sort: [
    SortDescriptor(\.name)
]) var model1Models: [Model1]

   var body: some View {
       VStack {
         Menu {
            ForEach(model1Models) { model in
                Button(model.name) {
                vm.model1Selection = model
                }
            }
         } label: {
            HStack {
               Text("\(vm.model1Selection?.name ?? "Select a Model")")
            }

         if let model1 = vm.model1Selection {
             ChildView1(selectedModel1: model1, selectedModel2:  
                  $vm.model2Selection)
         }
       }
       .onAppear {
        vm.model1Selection = model1Models.first
       }
   }
}
struct ChildView1: View {
let selectedModel1: Model1
@Binding var selectedModel2: Model2?
@State private var name: String = ""
@State private var searchActive: Bool = false

   var body: some View {
       VStack {
         if selectedModel2 == nil {
             TextField("...", text: $name, onEditingChanged: {
                self.searchActive = $0
                withAnimation {
                    proxy.scrollTo(anchor, anchor: .top)
                }
            })
         } else {
             Text("empty")
         }
         if searchActive {
            if !selectedModel1.models.isEmpty {  // <-- accessing models seems to be a problem
               ChildView2(selectedModel1: selectedModel1, 
                   selectedModel2: $selectedModel2)
            }
         }
       }
   }
}
struct ChildView2: View {
let selectedModel1: Model1

@Binding var selectedModel2: Model2?
   var body: some View {
       VStack {
         ForEach(model1.models) { x in
             Text(x.name)
         }
       }
   }
}

0 Answers0