如何阻止PDFView更新文档时自动获取焦点?
解决PDFView更新导致TextEditor失焦的问题
核心修复思路
问题根源是PDFView在更新文档时会自动尝试获取焦点,打断TextEditor的输入状态。可以通过禁用PDFView的焦点能力+强制保留TextEditor焦点的组合方案解决,同时优化更新逻辑减少不必要的刷新。
修改后的代码实现
1. 调整DocumentView的PDFView配置
import PDFKit import SwiftUI struct DocumentView: UIViewRepresentable { @Binding var source: String func generateDocument() -> PDFDocument? { let pdfRenderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 595, height: 842)) let data = pdfRenderer.pdfData { context in context.beginPage() let attributes = [ NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16) ] source.draw(at: CGPoint(x: 20, y: 50), withAttributes: attributes) } return PDFDocument(data: data) } func makeUIView(context: Context) -> PDFView { let pdfView = PDFView() // 禁止PDFView成为第一响应者,彻底阻止它抢焦点 pdfView.canBecomeFirstResponder = false pdfView.isFocusable = false // 若不需要PDF预览交互(如滚动、缩放),可额外禁用交互: // pdfView.isUserInteractionEnabled = false pdfView.document = generateDocument() return pdfView } func updateUIView(_ uiView: PDFView, context: Context) { // 优化:仅当内容真的变化时才更新文档,减少无效刷新 guard let currentDoc = uiView.document, let newDoc = generateDocument(), currentDoc.dataRepresentation() != newDoc.dataRepresentation() else { return } uiView.document = newDoc } }
2. 用FocusState强制维持TextEditor焦点
import SwiftUI struct ContentView: View { @State var source: String = "" @FocusState private var isTextEditorFocused: Bool var body: some View { HStack { TextEditor(text: $source) .focused($isTextEditorFocused) .onAppear { // 初始加载时自动让TextEditor获取焦点 isTextEditorFocused = true } DocumentView(source: $source) } .onChange(of: source) { _ in // 每次内容更新后,延迟恢复TextEditor焦点 DispatchQueue.main.async { isTextEditorFocused = true } } } }
关键修改说明
- 禁用PDFView焦点能力:通过
canBecomeFirstResponder = false和isFocusable = false,从UIKit层面阻止PDFView获取焦点,避免抢占TextEditor的输入状态。 - 优化更新逻辑:对比新旧PDF文档的二进制数据,仅在内容实际变化时更新文档,减少不必要的视图刷新操作。
- 强制维持焦点:利用SwiftUI的
FocusState管理焦点,每次内容更新后通过异步调度恢复TextEditor的焦点,确保输入流程不中断。
内容的提问来源于stack exchange,提问作者Cubik65536
相关产品推荐
相关产品推荐

