Swiftui 带UIViewRepresentable的UITextField和SwifUI之间绑定文本时出现问题

Swiftui 带UIViewRepresentable的UITextField和SwifUI之间绑定文本时出现问题,swiftui,uikit,uitextfield,uiviewrepresentable,Swiftui,Uikit,Uitextfield,Uiviewrepresentable,我正在尝试在SwiftUI中制作一个“表情选择器”,它会打开表情键盘,允许用户选择一个表情,然后关闭键盘。我正在使用一个UIViewRepresentable中包装的UITextField和一个字符串绑定,但是由于某种原因,字符串的值从未得到更新 以下是我目前掌握的代码: /// Allows a user to pick an emoji character using the Emoji keyboard. /// - Note: This does not prevent the user

我正在尝试在SwiftUI中制作一个“表情选择器”,它会打开表情键盘,允许用户选择一个表情,然后关闭键盘。我正在使用一个UIViewRepresentable中包装的UITextField和一个字符串绑定,但是由于某种原因,字符串的值从未得到更新

以下是我目前掌握的代码:

/// Allows a user to pick an emoji character using the Emoji keyboard.
/// - Note: This does not prevent the user from manually switching to other keyboards and inputting a non-Emoji character
struct EmojiPicker: UIViewRepresentable {
    @Binding var emoji: String
    
    func makeUIView(context: UIViewRepresentableContext<EmojiPicker>) -> EmojiUITextField {
        let textField = EmojiUITextField(frame: .zero)
        textField.text = emoji
        textField.delegate = context.coordinator
        textField.autocorrectionType = .no
        textField.returnKeyType = .done
        textField.textAlignment = .center
        textField.tintColor = .clear
        
        return textField
    }
    
    func updateUIView(_ uiView: EmojiUITextField, context: Context) {
        self.emoji = uiView.text!
    }
    
    func makeCoordinator() -> EmojiTextFieldCoordinator {
        return EmojiTextFieldCoordinator(self)
    }
}

internal class EmojiTextFieldCoordinator: NSObject, UITextFieldDelegate {
    var emojiTextField: EmojiPicker
    
    init(_ textField: EmojiPicker) {
        self.emojiTextField = textField
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        self.emojiTextField.emoji = textField.text!
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        textField.text = string
        
        if let text = textField.text, text.count == 1 {
            self.emojiTextField.emoji = textField.text!
            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
        
        return true
    }
}

internal class EmojiUITextField: UITextField {
    override var textInputContextIdentifier: String? {
        return ""
    }

    override var textInputMode: UITextInputMode? {
        return UITextInputMode.activeInputModes.first {
            $0.primaryLanguage == "emoji"
        }
    }
    
    override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] {
        return []
    }
}

到目前为止,我发现的所有资源都不起作用,包括,这里是fix,唯一修改的部分,用Xcode 12/iOS 14测试

func updateUIView(_ uiView: EmojiUITextField, context: Context) {
    if self.emoji != uiView.text! {     // << update only on change, otherwise
        self.emoji = uiView.text!       // it result in cycle and dropped
    }
}
这是一个用于测试的视图

struct ContentView: View {
    @State private var text = "<none>"
    var body: some View {
        VStack {
            Text("Get: \(text)")
            EmojiPicker(emoji: $text)
        }
    }
}

这里是fix,唯一修改的部分,使用Xcode 12/iOS 14进行测试

func updateUIView(_ uiView: EmojiUITextField, context: Context) {
    if self.emoji != uiView.text! {     // << update only on change, otherwise
        self.emoji = uiView.text!       // it result in cycle and dropped
    }
}
这是一个用于测试的视图

struct ContentView: View {
    @State private var text = "<none>"
    var body: some View {
        VStack {
            Text("Get: \(text)")
            EmojiPicker(emoji: $text)
        }
    }
}

嗯,它对我仍然不起作用。我使用的是iOS 14。事实上,这是因为在我的SwiftUI预览结构中,我直接使用了@State,而不是使用另一个结构。UpdateUI中的赋值感觉是向后的。updateUIView不应该从self.emoji的绑定中获取外部信息,并更新其外观以匹配吗?我认为这应该是uiView.text=self.emoji。然后,您需要使用addTarget在键入时更新self.emoji。如前所述,如果将表情符号分配给表情符号绑定,则此视图不会更新,对吗?下面是一个示例,我一直在基于您的代码进行研究,但UpdateUI视图的工作方向正好相反。嗯,它对我仍然不起作用。我使用的是iOS 14。事实上,这是因为在我的SwiftUI预览结构中,我直接使用了@State,而不是使用另一个结构。UpdateUI中的赋值感觉是向后的。updateUIView不应该从self.emoji的绑定中获取外部信息,并更新其外观以匹配吗?我认为这应该是uiView.text=self.emoji。然后,您需要使用addTarget在键入时更新self.emoji。如前所述,如果将表情符号分配给表情符号绑定,则此视图不会更新,对吗?下面是一个示例,我一直在基于您的代码进行研究,但UpdateUI视图的工作方向正好相反。