SwiftUI-将TextField获取到ForEach中的数组 [英] SwiftUI - Getting TextField to array in ForEach

查看:61
本文介绍了SwiftUI-将TextField获取到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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆