代码之家  ›  专栏  ›  技术社区  ›  William Hu

SwiftUI字符串似乎不正确

  •  0
  • William Hu  · 技术社区  · 4 年前

    我使用的是一个数组 List ,在 列表 有一个 ForEach ,例如:

    struct AView: View {
    
        @State var foo: [String] = ["a", "b", "c"]
    
        var body: some View {
            ZStack {
                Color.white
                List {
                    ForEach(foo.indices) { index in
                        Text(foo[index])
                    }
                }
            }
    
        }
    }
    

    这很好,然后我想添加一个按钮来插入新项目:

       List {
                ForEach(foo.indices) { index in
                    Text(foo[index])
                }
            }
            Button("Add") {
                foo.append("foo")
            }
        }
    

    ForEach<Range<Int>, Int, Text> 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`!
    

    这里提到

    Identifiable 或使用 ForEach(_:id:content:)

    我可以用 ForEach(foo.indices, id:\.self)

    我也想试试 可识别的 ,不要使用 id:\.self ForEach(foo.indices) .

    我给字符串添加了如下扩展:

    extension String: Identifiable {
        public var id: String { self }
    }
    

    编辑

    根据我的评论@newdev indices Int :

    extension Int: Identifiable {
        public var id: Int { self }
    }
    

    0 回复  |  直到 4 年前
        1
  •  2
  •   New Dev    4 年前

    ForEach 有多个 init 超载。

    init(Range<Int>, content: (Int) -> Content) 只适用于恒定范围-因此存在误差。

    init(Data, content: (Data.Element) -> Content) 要求 Data 符合 RandomAccessCollection 属于 Identifiable 元素。那是你想用的。

    问题是你的 随机访问集合 (对哪个 Range<Int> Int 元素。

    内景 ,这仍然不起作用。它仍然会使用第一个 ForEach.init 用一个 范围<内部> 匹配更具体的 具有 参数,而不是不太具体的 初始化 具有 .


    所以,你的选择是:

    1. 使用第三个 init(Data, id: KeyPath<Data.Element, ID>, content: (Data.Element) -> Content) 通过显式指定 id
    ForEach(foo.indices, id:\.self) { index in 
    }
    
    1. 转换为 Array<Int> 并符合 Int: Identifiable
    extension Int: Identifiable { var id: Self { self } }
    
    ForEach(Array(foo.indices)) { index in 
    }