4

バックグラウンド

私のアプリには、別のビューから追加できる友人の配列があります。この友人の配列をクラスに保存しましたObservableObject. メイン ビュー 内で、FriendListViewを使用しForEachて、ユーザーが追加した各フレンドのカスタム ビューを表示しています。

配列に追加して、リストに新しいアイテムを表示させることができませんでした。私は、理解してまとめることができたものに基づいて、2 つの異なる試みを試みました。誰かが提供できる助けをいただければ幸いです。現在、コメントアウトされた新しい友達を追加する2番目のビューを表示する方法があり、新しい友達を自動的に保存する方法がナビゲーションバーアイテムとして存在します。

試み

試み #1

クラス初期化中に配列に追加された場合、友人のリストを表示することに成功しました。クラスメソッドを呼び出して別のビューから配列に追加することは、配列の内容を印刷できることに基づいて機能しているようですが、UI は更新されません。

これはForEach(0..<Array.count)アプローチを使用して完了しましたが、新しいアイテムを追加した後、次のコンソール エラーが発生しました。

エラー

ForEach<Range<Int>, Int, HStack<TupleView<(Spacer, FriendView, Spacer)>>> count (4) != its initial count (3).
`ForEach(_:content:)` should only be used for *constant* data.
Instead conform data to `Identifiable` or use `ForEach(_:id:content:)` and provide an explicit `id`!

型式コード

struct Pet: Identifiable {
    var id = UUID().uuidString
    var name: String
    var breed: String
}

class FriendModel: ObservableObject {
    
    @Published var petList = [Pet]()
    
    func addFriend(name: String, breed: String) {
        petList.append(Pet(name: name, breed: breed))
    }
    
    init() {
        petList.append(Pet(name: "Woofer", breed: "Dawg"))
        petList.append(Pet(name: "Floofer", breed: "Dawg"))
        petList.append(Pet(name: "Super", breed: "Dawg"))
//        petList.append(Pet(name: "Dooper", breed: "Dawg"))
//        petList.append(Pet(name: "Booper", breed: "Dawg"))
    }
}

UI コード

struct FriendListView: View {   
    
    @EnvironmentObject var dataModel: FriendModel
    
    @State private var displayAddFriendSheet = false
    
    var body: some View {
        GeometryReader { geo in
            NavigationView {
                ScrollView {
                    ForEach(0..<self.dataModel.petList.count) { pet in
                        HStack {
                            Spacer()
                            FriendView(
                                name: self.dataModel.petList[pet].name,
                                breed: self.dataModel.petList[pet].breed,
                                screenWidth: geo.size.width,
                                randomPic: Int.random(in: 1...2)
                            )
//                            FriendView(
//                                name: self.dataModel.petList[pet].name,
//                                breed: self.dataModel.petList[pet].breed,
//                                screenWidth: geo.size.width)
                            Spacer()
                        }
                    }
                }// End of ScrollView
                .navigationBarTitle(Text("Furiends"))
                    .navigationBarItems(trailing: Button(action: self.showAddFriend) {
                    Image(systemName: "plus")
                }
                
                )
                .sheet(isPresented: self.$displayAddFriendSheet) {
                        AddFriendView()
                }
                
            }// End of NavigationView
        }// End of GeometryReader geo1
    }// End of body
    
    func showAddFriend() {
//        self.displayAddFriendSheet.toggle()
        self.dataModel.addFriend(name: "Jax", breed: "Doodle")
        print(dataModel.petList)
        
    }// Enf of showAddFriend
    
}// End of FriendListView

試み #2

最初の試行でエラーが表示された後、構造体に UUID を使用しForEachてプロトコルに準拠しているため、範囲をスキップして配列の一部として提供する方法を読みました。モデル コードは最初の試みと同じままで、更新された UI コードは以下のとおりです。唯一の変更は ForEach でしたが、次のエラーを受け取りました。IdentifiablePet

エラー Cannot convert value of type '[Pet]' to expected argument type 'Range<Int>'

UI コード

struct FriendListView: View {   
    
    @EnvironmentObject var dataModel: FriendModel
    
    @State private var displayAddFriendSheet = false
    
    var body: some View {
        GeometryReader { geo in
            NavigationView {
                ScrollView {
                    ForEach(self.dataModel.petList) { pet in  // <--- Changed to directly reference the array
                        HStack {
                            Spacer()
                            FriendView(
                                name: self.dataModel.petList[pet].name,
                                breed: self.dataModel.petList[pet].breed,
                                screenWidth: geo.size.width,
                                randomPic: Int.random(in: 1...2)
                            )
//                            FriendView(
//                                name: self.dataModel.petList[pet].name,
//                                breed: self.dataModel.petList[pet].breed,
//                                screenWidth: geo.size.width)
                            Spacer()
                        }
                    }
                }// End of ScrollView
                .navigationBarTitle(Text("Furiends"))
                    .navigationBarItems(trailing: Button(action: self.showAddFriend) {
                    Image(systemName: "plus")
                }
                
                )
                .sheet(isPresented: self.$displayAddFriendSheet) {
                        AddFriendView()
                }
                
            }// End of NavigationView
        }// End of GeometryReader geo1
    }// End of body
    
    func showAddFriend() {
//        self.displayAddFriendSheet.toggle()
        self.dataModel.addFriend(name: "Jax", breed: "Doodle")
        print(dataModel.petList)
        
    }// Enf of showAddFriend
    
}// End of FriendListView
4

1 に答える 1