首页 > 解决方案 > 读取@Binding 值

问题描述

我尝试制作自定义文本字段,所以我给它@Binding 以响应如下所示的文本值,问题是当我尝试检测文本的更改时,它只是在“预览”中的响应,但是当在“模拟器”没有响应,我尝试了很多不同的方法来解决这个问题,但没有任何效果。

import SwiftUI

struct MyTextField: UIViewRepresentable {
    
    typealias UIViewType = UITextField
    
    @Binding var becomeFirstResponder: Bool
    @Binding var text: String
    var placeholder = ""
    
    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField()
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.widthAnchor.constraint(equalToConstant: 320).isActive = true
        
        textField.textColor = UIColor.systemBlue
        textField.font = UIFont.boldSystemFont(ofSize: 22)
        
        textField.textAlignment = .left
        textField.keyboardType = .default
        
        textField.minimumFontSize = 13
        textField.adjustsFontSizeToFitWidth = true
        
        textField.text = self._text.wrappedValue
        textField.placeholder = self.placeholder
        textField.delegate = context.coordinator
        
        return textField
    }
    
    func updateUIView(_ textField: UITextField, context: Context) {
        if self.becomeFirstResponder {
            DispatchQueue.main.async {
                textField.becomeFirstResponder()
                self.becomeFirstResponder = false
            }
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: MyTextField
        
        init(parent: MyTextField) {
            self.parent = parent
        }
        
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            textField.resignFirstResponder()
        }
        
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            
            let currentText = textField.text ?? ""
            
            guard let stringRange = Range(range, in: currentText) else {
                return false
            }
            
            let updateText = currentText.replacingCharacters(in: stringRange, with: string)
            
            return updateText.count < 20
            
        }
    }
}



struct TextFieldFirstResponder: View {
    
    @State private var becomeFirstResponder = false
    @State private var text = "LLL"
    private var placeholder = "Untitled"
    
    var body: some View {
        
        VStack {
            ZStack(alignment: .trailing) {
                MyTextField(becomeFirstResponder: self.$becomeFirstResponder, text: self.$text, placeholder: self.placeholder)
                    .frame(width: 343, height: 56, alignment: .leading)
                    .padding(EdgeInsets(top: 27, leading: 13, bottom: 0, trailing: 0))
                    .background(
                        RoundedRectangle(cornerRadius: 10, style: .continuous)
                            .fill(Color(UIColor.secondarySystemBackground))
                            .frame(width: 342, height: 56, alignment: .center)
                    )
                    .onAppear {
                        self.becomeFirstResponder = true
                    }
            }
            Text("\(self.$text.wrappedValue)") // <------ Do not read the "text"
        }
    }
}

struct TextFieldFirstResponder_Previews: PreviewProvider {
    static var previews: some View {
        TextFieldFirstResponder()
    }
}

标签: swiftuitextfield

解决方案


这里不需要使用$,直接读取属性

Text(self.text) // <------ Do not use $

我假设你想通过绑定来更新它

let updateText = currentText.replacingCharacters(in: stringRange, with: string)
self.parent.text = updateText          // << here !!
return updateText.count < 20

测试和使用 Xcode 12.1 / iOS 14.1


推荐阅读