SwiftUI - 在 ForEach 中获取 TextField 数组

Posted

技术标签:

【中文标题】SwiftUI - 在 ForEach 中获取 TextField 数组【英文标题】:SwiftUI - Getting TextField to array in ForEach 【发布时间】:2020-09-11 00:27:25 【问题描述】:

我们的目标是拥有一个TextField,它在输入字符时接受字符,并将它们显示在TextField 下方的“堆”中。我的意思是,每个新字符都显示在最后一个字符的顶部。将字母堆积起来很容易——我使用ForEach 循环遍历ZStack 内的数组。为了获取数组中的字符,我使用了自定义绑定。它有效,但问题是每次输入新字符时字符都会重复。例如,如果用户键入 CAT,首先会出现 C,然后在 C 的顶部出现 CA,然后在 CA 和 C 的顶部出现 CAT。换句话说,当我只想要三个时,堆叠了六个字符。

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 捕获并转换为字符数组。请注意,我必须使用 map 从字符数组转换为字符串数组,因为 ForEach 不适用于字符。

class ViewModel: ObservableObject 
    @Published var letterArray = [String]()
    @Published var letter = "" 
        didSet 
            letterArray = Array(letter).map  String($0) 
        
    

在ContentView中,我只需要@ObservedObject var vm = ViewModel(),那么我使用vm.lettervm.letterArray引用变量

【问题讨论】:

【参考方案1】:

我遇到您问题的住宅区,下面的代码可能对您有所帮助 我修改了你的代码如下;

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 - 在 ForEach 中获取 TextField 数组的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI ForEach获取2d数组中的元素AND索引

SwiftUI - 如果在 ForEach 循环内

SwiftUI 在 For Each 中获取下一个循环的值

SwiftUI ForEach 获取二维数组中的元素和索引

使用 SwiftUI ForEach 从 NSOrderedSet 获取字符串值

SwiftUI .onDelete 从 ForEach 获取 var