【问题标题】:Conditionally Text in SwiftUI depending on Array valueSwiftUI 中的有条件文本取决于数组值
【发布时间】:2020-01-28 17:09:26
【问题描述】:

我想制作占位符自定义样式,所以我尝试在SwiftUI. How to change the placeholder color of the TextField?中使用 Mojtaba Hosseini 的方法

if text.isEmpty {
            Text("Placeholder")
                .foregroundColor(.red)
        }

但在我的情况下,我使用带有数组的 foreach 来制作 Textfield 和 Display 的列表,或者不使用 Text 来模拟自定义占位符。

          ForEach(self.ListeEquip.indices, id: \.self) { item in
     ForEach(self.ListeJoueurs[item].indices, id: \.self){idx in
// if self.ListeJoueurs[O][O] work
        if self.ListeJoueurs[item][index].isEmpty {
                                    Text("Placeholder")
                                        .foregroundColor(.red)
                                }
    }
    }

如何将动态条件与 foreach 一起使用?


现在我有另一个问题:

我有这个代码:

struct EquipView: View {
    @State var ListeJoueurs = [
        ["saoul", "Remi"],
        ["Paul", "Kevin"]
    ]
    @State var ListeEquip:[String] = [
        "Rocket", "sayans"
    ]

    var body: some View {
        VStack { // Added this
            ForEach(self.ListeEquip.indices) { item in

                BulleEquip(EquipName: item, ListeJoueurs: self.$ListeJoueurs, ListeEquip: self.$ListeEquip)

            }
        }
    }

}


struct BulleEquip: View {
    var EquipName = 0
    @Binding var ListeJoueurs :[[String]]
    @Binding var ListeEquip :[String]

    var body: some View {
        VStack{
        VStack{
            Text("Équipe \(EquipName+1)")
        }
        VStack { // Added this
            ForEach(self.ListeJoueurs[EquipName].indices) { index in
                ListeJoueurView(EquipNamed: self.EquipName, JoueurIndex: index, ListeJoueurs: self.$ListeJoueurs, ListeEquip: self.$ListeEquip)
            }
            HStack{
            Button(action: {
                self.ListeJoueurs[self.EquipName].append("")  //problem here
            }){
                Text("button")
                }
            }
        }
    }
    }

}

struct ListeJoueurView: View {
    var EquipNamed = 0
    var JoueurIndex = 0
    @Binding var ListeJoueurs :[[String]]
    @Binding var ListeEquip :[String]

    var body: some View {
        HStack{
            Text("Joueur \(JoueurIndex+1)")
        }
    }

}

我可以运行应用程序,但是当我单击按钮时,控制台中出现此错误: ForEach, Int, ListeJueurView> count (3) != 它的初始计数 (2)。 ForEach(_:content:) 应该只用于 constant 数据。而是将数据符合Identifiable 或使用ForEach(_:id:content:) 并提供明确的id

谁能启发我?

【问题讨论】:

    标签: if-statement text view conditional-statements swiftui


    【解决方案1】:

    TL;DR

    每个ForEach 之外都需要VStackHStackList 等。

    更新

    对于问题的第二部分,您需要更改 ForEach 以包含 id 参数:

    ForEach(self.ListeJoueurs[EquipName].indices, id: \.self)
    

    如果数据不是常量并且元素的数量可能会发生变化,则需要包含id: \.self,以便 SwiftUI 知道在哪里插入新视图。

    示例

    这里有一些示例代码演示了一个有效的嵌套 ForEach。我创建了一个与您尝试调用它的方式相匹配的数据模型。

    struct ContentView: View {
    
        // You can ignore these, since you have your own data model
        var ListeEquip: [Int] = Array(1...3)
        var ListeJoueurs: [[String]] = []
        // Just some random data strings, some of which are empty
        init() {
            ListeJoueurs = (1...4).map { _ in (1...4).map { _ in Bool.random() ? "Text" : "" } }
        }
    
        var body: some View {
            VStack { // Added this
                ForEach(self.ListeEquip.indices, id: \.self) { item in
                    VStack { // Added this
                        ForEach(self.ListeJoueurs[item].indices, id: \.self) { index in
                            if self.ListeJoueurs[item][index].isEmpty { // If string is blank
                                Text("Placeholder")
                                    .foregroundColor(.red)
                            } else { // If string is not blank
                                Text(self.ListeJoueurs[item][index])
                            }
                        }
                    }.border(Color.black)
                }
            }
        }
    }
    

    说明

    Apple's documentation 对 ForEach 的评价如下:

    一种根据 [sic] 已识别数据的基础集合按需计算视图的结构。

    类似

    ForEach(0..2, id: \.self) { number in
        Text(number.description)
    }
    

    实际上只是

    的简写
    Text("0")
    Text("1")
    Text("2")
    

    所以你的 ForEach 正在创建一堆视图,但是这种声明视图的语法只在 VStack、HStack、List、Group 等视图内有效。技术原因是因为这些视图有一个看起来像

    init(..., @ViewBuilder content: () -> Content)
    

    @ViewBuilder 做了一些神奇的事情来允许这种独特的语法。

    【讨论】:

    • 当我尝试在第一个 Foreach 中使用按钮“self.ListeJoueurs[item].append("one more")”在 ListeJoueurs 添加字符串时,我有“无法使用通用参数“数据”推断”错误,如何解决?
    • @NicolasM 我为我的答案添加了更新。您需要在 ForEach 中包含 id 参数。
    猜你喜欢
    • 2021-10-30
    • 1970-01-01
    • 2020-07-26
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 2017-12-08
    • 1970-01-01
    相关资源
    最近更新 更多