简体   繁体   中英

SwiftUI : How can I change the index from a view and show the correct Text in another view?

I don't understand why my DetailView is showing the same Text. (gif below)

Indeed I implemented a method selectTheme in ContentView that should change the selectedIndex according to the index of the row when the DetailView Appears but it seems that it does not take into account the var selectedIndex in my ViewModel remains 0.

Do you have any idea why? I really don't understand what going wrong here.

Thank you.

struct ContentView: View {
    var vm:ViewModel
    var body: some View {
        NavigationView{
            List{
                ForEach(vm.sentences, id:\.self) { indexNumb in
                    NavigationLink(destination: DetailView(vm: vm).onAppear(perform: {
                        vm.selectTheme(sentence: indexNumb)
                        print(vm.groupedItems)
                        print("Array :\(vm.sylbArray)")
                        
                    })) {
                        Text(String(indexNumb))
                        
                    }
                }
                
            }
        }
    }
}

struct DetailView: View {
    var vm:ViewModel
    
    var body: some View {
        
        ForEach(vm.groupedItems,id:\.self) { subItems in
            HStack{
                
                ForEach(subItems,id:\.self) { word in
                    
                    Button(action: {
                        print(vm.groupedItems)
                        print(vm.selectedIndex)
                        
                    }, label: {
                        Text(word)
                    })
                    
                }
            }
        }
    }
}
class ViewModel{
    
    @Published var sylbArray: [String] = []
    var groupedItems: [[String]] = []
    
    init() {
        appendArray(string: String(sentences[selectedIndex]))
        groupedItems = [sylbArray]
    }
    
    var sentences = [13,4]
    
    func appendArray(string: String) {
        sylbArray.append(string)
    }
    
//  remains  0 : why ? 
    var selectedIndex = 0
    
    func selectTheme(sentence: Int) {
        if let index = sentences.firstIndex(of: sentence) {
            selectedIndex = index
        }
    }
}

gif 例子

Your viewModel must conform to class protocol 'ObservableObject'

class ViewModel: ObservableObject {
    var sentences = [13, 4]
    @Published var selectedSentens: Int?
}

here is an example of what you want to do.

struct ContentView: View {
    @StateObject var vm: ViewModel = .init()
    var body: some View {
        NavigationSplitView {
            List(vm.items, selection: $vm.selectedItem) { item in
                Text(item.name)
                    .tag(item)
            }
        } detail: {
            if let item = vm.selectedItem{
                DetailView(for: item)
            }
        }
        .navigationSplitViewStyle(.balanced)
    }
}

item object:

struct Item: Hashable, Identifiable {
    var name: String
    var subItems: [String]
    var id = UUID()
}

viewModel class

class ViewModel: ObservableObject {
    var items: [Item] = [
        Item(name: "Item 1", subItems: [ "sub 11", "sub 12" ] ),
        Item(name: "Item 2", subItems: [ "sub 21", "sub 22" ] )
    ]
    @Published var selectedItem: Item?
}

DetailView:

struct DetailView: View {
    var item: Item
    init(for item: Item) {
        self.item = item
    }
    var body: some View {
        List(item.subItems, id: \.self){ subItem in
            Text(subItem)
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM