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

SwiftUI中如何编辑ForEach内NavigationLink标签中的数组元素属性

解决方案

一、点击TextField触发跳转的修复

该问题的核心是NavigationLink默认会捕获其label范围内所有点击事件,非List容器下苹果未做点击区域的特殊区分,按如下方式修改即可:

  1. 改用编程式导航,仅在非编辑状态下点击卡片主体才触发跳转
  2. 对编辑按钮、TextField添加独立点击响应,阻断NavigationLink的点击捕获

二、TextField显示时自动全选内容的实现

通过@FocusState控制TextField聚焦状态,配合UITextField的原生选中文本能力实现自动全选。

完整修改后代码

1. ContentView 修改

struct ContentView: View {
    @EnvironmentObject var allPlaces: ViewModel
    // 存储当前选中要跳转的Collection,iOS16+适用,低版本可改用isActive绑定
    @State var selectedCollection: Collection?
    var body: some View {
        NavigationView {
            // 替换为你需要的ScrollView+LazyVGrid即可
            ScrollView {
                LazyVStack {
                    ForEach($allPlaces.displayedCollectionsArray) { $collection in
                        VStack {
                            CollectionCardView(collection: $collection, isHidden: false)
                            // 仅非编辑状态下点击才触发跳转
                                .onTapGesture {
                                    selectedCollection = collection
                                }
                        }
                    }
                }
            }
            .navigationDestination(item: $selectedCollection) { collection in
                Text("Detail View of \(collection.name)")
            }
            .navigationBarHidden(true)
        }
    }
}

2. CollectionCardView 修改

struct CollectionCardView: View {
    @Binding var collection: Collection
    @State var isHidden: Bool = false
    let testkey = "hello"
    // 控制TextField聚焦
    @FocusState var isFocused: Bool
    var body: some View {
        VStack (alignment: .leading) {
            HStack {
                ZStack (alignment: .leading) {
                    Text(collection.name)
                        .foregroundColor(Color.black)
                        .opacity(isHidden ? 0 : 1)
                        .frame(width: 200, height: 40, alignment: .leading)
                    if collection.name != "Travel gems" {
                        TextField(testkey, text: $collection.name)
                            .foregroundColor(Color.black)
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                            .frame(width: 200, height: 40, alignment: .leading)
                            .opacity(isHidden ? 1 : 0)
                            .focused($isFocused)
                            // 阻断NavigationLink的点击捕获
                            .onTapGesture {}
                            // 聚焦时自动全选文本
                            .onChange(of: isFocused) { newValue in
                                if newValue {
                                    DispatchQueue.main.async {
                                        UIApplication.shared.sendAction(#selector(UIResponder.selectAll(_:)), to: nil, from: nil, for: nil)
                                    }
                                }
                            }
                    }
                }
                if collection.name != "Travel gems" {
                    Image(systemName: "square.and.pencil")
                        .foregroundColor(Color.gray)
                        .onTapGesture {
                            isHidden.toggle()
                            isFocused = isHidden
                        }
                }
            }
            .padding(.leading, 24)
            .padding(.trailing, 24)
        }
        .padding(.top, 10)
        .padding(.bottom, 10)
    }
}

额外说明

  • 原有代码中将collecName作为局部@State的写法无法同步修改到环境对象的数组中,这里改为直接绑定数组元素的name属性,修改后会自动同步到ViewModel
  • 如果需要兼容iOS15及以下版本,把navigationDestination替换为带isActive绑定的隐形NavigationLink即可
  • 替换外层容器为LazyVGrid即可满足你生产环境的布局需求,导航逻辑不需要修改

内容的提问来源于stack exchange,提问作者christianzags

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:54:05