SwiftUI TextEditor如何禁用编辑同时保留点击交互能力
问题原因
.disabled()修饰符会完全禁用视图的所有交互响应能力,因此添加该修饰符后TextEditor的点击手势也会同步失效。
以下提供两种无需封装UIViewRepresentable的实现方案:
方案1:禁用TextEditor自身交互(无额外依赖,实现最简单)
直接给TextEditor添加allowsHitTesting(false)修饰符,禁止其自身接收任何交互事件,点击事件会自动透传到上层父视图,既可以触发你已经写好的onTapGesture,用户也无法编辑内容。
修改后的TextBox代码如下:
struct TextBox: View { @Binding var text: String var placeholder: String var multiLine: Bool var body: some View { ZStack(alignment: .topLeading) { TextEditor(text: $text) .introspectTextField { textfield in textfield.returnKeyType = .next } .background(Color.white) .overlay( RoundedRectangle(cornerRadius: 5) .stroke(Color.black, lineWidth: 1) ) .padding(.horizontal, 8) .allowsHitTesting(false) // 新增该行代码 if text.isEmpty { Text(placeholder) .foregroundColor(.black.opacity(0.25)) .padding(.top, 8) .padding(.horizontal, 12) .allowsHitTesting(false) } } } }
该方案无需修改你原有业务层的任何代码,直接生效。如果你的TextEditor内容不长不需要滚动,优先选该方案。
方案2:仅禁用编辑能力,保留滚动交互
如果你需要保留TextEditor的滚动能力(用于查看长文本),可以通过你已经引入的Introspect库拿到底层的UITextView,仅关闭编辑权限,其他交互能力完全保留:
修改TextEditor的Introspect部分代码即可:
TextEditor(text: $text) // 注意替换为introspectTextView,TextEditor底层对应UITextView .introspectTextView { textView in textView.returnKeyType = .next textView.isEditable = false // 仅禁用编辑,滚动、点击响应都保留 } .background(Color.white) .overlay( RoundedRectangle(cornerRadius: 5) .stroke(Color.black, lineWidth: 1) ) .padding(.horizontal, 8)
该方案下用户可以正常滑动查看长文本,同时无法编辑内容,上层的点击手势也能正常触发。
内容的提问来源于stack exchange,提问作者user16253584
相关产品推荐
相关产品推荐

