SwiftUI中为UITextView添加清除按钮的实现问题
SwiftUI中清空UITextView文本的解决方案
问题根源
你的代码核心问题是TextInputView中的text属性使用了@State而非@Binding,导致父视图的content无法和UITextView的文本实现双向绑定,直接设置content = ""无法同步到底层的UITextView。
修复步骤及代码
1. 修正TextInputView的绑定关系
将text属性改为@Binding,补充desiredHeight和hasContent的绑定(原代码中父视图传递了这两个参数但子视图未定义),并优化更新逻辑避免循环刷新:
struct TextInputView: UIViewRepresentable { @Binding var text: String @Binding var desiredHeight: CGFloat @Binding var hasContent: Bool var foregroundColor: Color = .gray func makeUIView(context: Context) -> UITextView { let view = UITextView() view.font = .systemFont(ofSize: 16) view.textColor = UIColor(foregroundColor) view.isEditable = true view.isScrollEnabled = true view.delegate = context.coordinator return view } func updateUIView(_ uiView: UITextView, context: Context) { // 仅当文本不一致时更新,避免循环刷新 if uiView.text != text { uiView.text = text } uiView.textColor = UIColor(foregroundColor) // 同步内容状态 hasContent = !text.isEmpty } func makeCoordinator() -> Coordinator { Coordinator(text: $text, hasContent: $hasContent) } class Coordinator: NSObject, UITextViewDelegate { @Binding var text: String @Binding var hasContent: Bool init(text: Binding<String>, hasContent: Binding<Bool>) { _text = text _hasContent = hasContent } func textViewDidChange(_ textView: UITextView) { text = textView.text hasContent = !text.isEmpty } } }
2. 修正父视图Input的绑定传递
确保向TextInputView传递绑定值,并在按钮点击事件中直接清空content:
struct Input: View { @State var content: String = "" var hint: String = "" @State private var style: Style = .idle @FocusState private var isFocused: Bool @State private var desiredHeight: CGFloat = 100 @State private var hasContent: Bool = false var body: some View { HStack { VStack(alignment: .leading) { TextInputView( text: $content, desiredHeight: $desiredHeight, hasContent: $hasContent ) .focused($isFocused) .onChange(of: isFocused) { isFocused in withAnimation { style = isFocused ? .focused : .idle } } } Button { // 直接清空绑定的content即可 content = "" } label: { Text("Press Me") } .hidden(!(hasContent && isFocused)) .padding(.trailing, 16) } } enum Style { case idle, focused } }
关键说明
- 使用
@Binding建立父视图与子视图的双向数据同步,确保清空content时,UITextView的文本会同步更新 - 在
updateUIView中加入文本判断,避免UITextView内容变化时触发无限循环更新 - 通过
hasContent的双向绑定,确保清除按钮的显示隐藏状态与文本内容同步
内容的提问来源于stack exchange,提问作者The clear button awaits
相关产品推荐
相关产品推荐

