Nic*_*s M 2 text if-statement view conditional-statements swiftui
我想制作占位符自定义样式,所以我尝试在SwiftUI 中使用 Mojtaba Hosseini 的方法。如何更改 TextField 的占位符颜色?
if text.isEmpty {
Text("Placeholder")
.foregroundColor(.red)
}
Run Code Online (Sandbox Code Playgroud)
但就我而言,我使用带有 Array 的 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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何在 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)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我可以运行应用程序,但是当我单击按钮时,控制台中出现此错误:ForEach, Int, ListeJoueurView> count (3) != its initial count (2)。ForEach(_:content:)应该只用于常量数据。而是使数据符合Identifiable或使用ForEach(_:id:content:)并提供明确的id!
有人可以启发我吗?
你需要一个VStack,HStack,List外各等ForEach。
更新
对于问题的第二部分,您需要更改 ForEach 以包含 id 参数:
ForEach(self.ListeJoueurs[EquipName].indices, id: \.self)
Run Code Online (Sandbox Code Playgroud)
如果数据不是恒定的并且元素的数量可能会发生变化,您需要包含id: \.selfSwiftUI 知道在哪里插入新视图。
下面是一些演示工作嵌套 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)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是Apple 的文档中关于 ForEach 的说明:
一种根据[原文如此]识别数据的基础集合按需计算视图的结构。
所以像
ForEach(0..2, id: \.self) { number in
Text(number.description)
}
Run Code Online (Sandbox Code Playgroud)
真的只是简写
Text("0")
Text("1")
Text("2")
Run Code Online (Sandbox Code Playgroud)
所以你的 ForEach 正在制作一堆视图,但是这种声明视图的语法只在 VStack、HStack、List、Group 等视图内有效。技术原因是因为这些视图有一个看起来像
init(..., @ViewBuilder content: () -> Content)
Run Code Online (Sandbox Code Playgroud)
这@ViewBuilder做了一些允许这种独特语法的魔法。