SwiftUI-将TextField获取到ForEach中的数组 [英] SwiftUI - Getting TextField to array in ForEach
问题描述
目标是要有一个 TextField
来接受输入时的字符,并以"pile"形式将其显示在 TextField
下方.我的意思是,每个新角色都显示在最后一个角色的顶部.堆积字母很容易-我使用 ForEach
遍历 ZStack
中的数组.为了获得数组中的字符,我使用了自定义绑定.它可以工作,但是问题在于,每次键入新字符时,字符都会重复出现.例如,如果用户键入CAT,则首先将显示C,然后在C的顶部出现CA,然后在CA和C的顶部出现CAT.换句话说,当我只需要三个字符时,就会堆叠六个字符.
The goal is to have a TextField
that takes characters as they're being entered and display them below the TextField
in a 'pile'. By pile I mean, each new character is displayed on top of the last one. Piling the letters up is easy enough - I use ForEach
to loop over an array inside a ZStack
. To get the characters in the array, I used a custom binding. It works, but the problem is that the characters get repeated each time a new character is typed. For example, if the user types CAT, first the C will appear, then CA on top of the C, then CAT on top of the CA and the C. In other words, there are six characters stacked up when I only wanted three.
struct ContentView: View {
@State private var letter = ""
@State private var letterArray = [String]()
var body: some View {
let binding = Binding<String>(
get: { self.letter },
set: { self.letter = $0
self.letterArray.append(self.letter)
})
return VStack {
TextField("Type letters and numbers", text: binding)
ZStack {
ForEach(letterArray, id: \.self) { letter in
Text(letter)
}
}
}
}
}
更新:我使这个问题变得更加困难了.通过使用 ObservableObject
,我能够从视图中分离逻辑并简化代码.首先,我创建了一个视图模型.现在,每次用户在 TextField
中键入内容时,它都会被 didSet
捕获并转换为字符数组.请注意,由于 ForEach
不适用于字符,因此必须使用map从字符数组转换为字符串数组.
UPDATE:
I was making the problem a little more difficult that it was. By using an ObservableObject
I was able to separate the logic from the view AND simplify the code. First I created a view model. Now, each time the user types something into a TextField
, it's it's caught by didSet
and converted into an array of characters. Note, I had to use map to convert from a character array to a string array because ForEach
doesn't work with characters.
class ViewModel: ObservableObject {
@Published var letterArray = [String]()
@Published var letter = "" {
didSet {
letterArray = Array(letter).map { String($0) }
}
}
}
在ContentView中,我只需要 @ObservedObject var vm = ViewModel()
然后,我使用 vm.letter
或 vm.letterArray 引用变量代码>
In ContentView, I only need @ObservedObject var vm = ViewModel()
Then I refer to the variables using vm.letter
or vm.letterArray
推荐答案
我遇到问题的住宅区,下面的代码可能对您有帮助我修改了您的代码,如下所示;
Uptown where I get your problem may the below code help you I modified your code as below;
struct ContentView: View {
@State private var letter = ""
@State private var letterCounter = 0
@State private var letterArray = [String]()
var body: some View {
let binding = Binding<String>(
get: { self.letter },
set: { self.letter = $0
if self.letter.count > self.letterCounter {
if let lastLetter = self.letter.last{
self.letterArray.append(String(lastLetter))
}
}else{
_ = self.letterArray.removeLast()
}
self.letterCounter = self.letter.count
})
return VStack {
TextField("Type letters and numbers", text: binding)
VStack {
ForEach(letterArray, id: \.self) { letter in
Text(letter)
}
}
}
}
}
这篇关于SwiftUI-将TextField获取到ForEach中的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!