You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何从另一个视图向数组追加数据?

SwiftUI 跨视图数据传递解决方案

问题根源分析

  1. 第一个报错:AddFriendView 未声明 friends 属性,也未通过绑定获取父视图的数组,导致无法访问该变量。
  2. 预览报错:为 AddFriendView 添加 @Binding var friends: [Friend] 后,预览代码未传入必填的绑定参数,引发缺失参数错误。

完整实现步骤

1. 定义 Friend 模型

首先需要一个符合列表展示要求的模型,实现 Identifiable 协议:

struct Friend: Identifiable {
    let id = UUID()
    var name: String
    var birthday: Date
}

2. 实现 AddFriendView(带绑定参数)

通过 @Binding 接收父视图传递的好友数组,同时用 @State 管理输入框的临时数据:

struct AddFriendView: View {
    @Binding var friends: [Friend]
    @State private var nameInput = ""
    @State private var birthdayInput = Date()
    
    var body: some View {
        VStack(spacing: 20) {
            TextField("输入姓名", text: $nameInput)
                .textFieldStyle(.roundedBorder)
            
            DatePicker("选择生日", selection: $birthdayInput, displayedComponents: .date)
                .datePickerStyle(.compact)
            
            Button("添加好友") {
                addFriend()
            }
        }
        .padding()
    }
    
    private func addFriend() {
        guard !nameInput.isEmpty else { return } // 过滤空姓名输入
        let newFriend = Friend(name: nameInput, birthday: birthdayInput)
        friends.append(newFriend)
        // 清空输入框
        nameInput = ""
        birthdayInput = Date()
    }
}

3. 实现 FriendView(仅展示数据)

仅需接收好友数组用于展示,无需绑定:

struct FriendView: View {
    let friends: [Friend]
    
    var body: some View {
        List(friends) { friend in
            VStack(alignment: .leading) {
                Text(friend.name)
                    .font(.headline)
                Text(friend.birthday.formatted(date: .long, time: .omitted))
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
        }
        .navigationTitle("好友列表")
    }
}

4. 父视图管理数据源

用 @State 持有好友数组,作为数据源的所有者,分别传递给两个子视图:

struct ContentView: View {
    @State private var friends: [Friend] = []
    
    var body: some View {
        NavigationStack {
            VStack {
                AddFriendView(friends: $friends)
                Divider()
                FriendView(friends: friends)
            }
        }
    }
}

5. 修复预览代码

为 AddFriendView 的预览创建测试用的绑定数组,为 FriendView 传入测试数据:

// AddFriendView 预览
struct AddFriendView_Previews: PreviewProvider {
    @State static var testFriends: [Friend] = [
        Friend(name: "张三", birthday: Date())
    ]
    
    static var previews: some View {
        AddFriendView(friends: $testFriends)
    }
}

// FriendView 预览
struct FriendView_Previews: PreviewProvider {
    static let testFriends: [Friend] = [
        Friend(name: "李四", birthday: Date()),
        Friend(name: "王五", birthday: Date().addingTimeInterval(-365*24*60*60))
    ]
    
    static var previews: some View {
        FriendView(friends: testFriends)
    }
}

关键注意事项

  • 数据源统一由父视图持有(@State),子视图通过 @Binding 修改数据,符合 SwiftUI 单向数据流原则。
  • 添加好友时增加空值判断,避免无效数据存入数组。
  • 模型实现 Identifiable 协议,简化列表视图的使用。

内容的提问来源于stack exchange,提问作者Viktor Goleš

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:55:16