iOS17中如何在WKWebView隐藏键盘同时保持输入焦点
解决WKWebView保持编辑状态下收起键盘且不重置滚动偏移的问题
问题分析
你当前通过让WKWebView失焦收起键盘的方式,会导致重新聚焦时内部scrollView偏移被重置——核心原因是WKWebView重新成为第一响应者时,会自动将scrollView滚动到光标位置或顶部,覆盖原有偏移状态。
解决方案
方案1:保存并恢复scrollView偏移量(合规稳定的公开API方案)
通过在WKWebView失焦前保存当前滚动偏移,重新聚焦后立即恢复该偏移,避免系统自动重置。
步骤1:定义变量保存偏移和恢复标记
// Objective-C @property (nonatomic, assign) CGPoint savedWebViewOffset; @property (nonatomic, assign) BOOL shouldRestoreOffset;
// Swift private var savedWebViewOffset: CGPoint = .zero private var shouldRestoreOffset = false
步骤2:点击添加按钮时保存偏移并收起键盘
// Objective-C - (void)onAddButtonTapped { // 保存当前滚动偏移 self.savedWebViewOffset = self.webView.scrollView.contentOffset; self.shouldRestoreOffset = YES; // 让webView失焦收起键盘 [self.webView resignFirstResponder]; // 显示后方的collectionView [self showCollectionView]; }
// Swift @objc func onAddButtonTapped() { // 保存当前滚动偏移 savedWebViewOffset = webView.scrollView.contentOffset shouldRestoreOffset = true // 让webView失焦收起键盘 webView.resignFirstResponder() // 显示后方的collectionView showCollectionView() }
步骤3:监听webView聚焦事件,恢复偏移
让控制器遵守WKNavigationDelegate(或直接实现WKWebView的响应者代理方法),设置webView.navigationDelegate = self后,实现以下方法:
// Objective-C - (void)webViewDidBecomeFirstResponder:(WKWebView *)webView { if (self.shouldRestoreOffset) { // 强制恢复之前保存的偏移,关闭动画避免闪烁 [webView.scrollView setContentOffset:self.savedWebViewOffset animated:NO]; self.shouldRestoreOffset = NO; } }
// Swift func webViewDidBecomeFirstResponder(_ webView: WKWebView) { guard shouldRestoreOffset else { return } // 强制恢复之前保存的偏移,关闭动画避免闪烁 webView.scrollView.setContentOffset(savedWebViewOffset, animated: false) shouldRestoreOffset = false }
步骤4:回到编辑状态的处理
当需要重新打开键盘继续编辑时(比如点击collectionView选项或返回按钮),直接调用:
// Objective-C [self.webView becomeFirstResponder];
// Swift webView.becomeFirstResponder()
此时webView会自动尝试重置偏移,但我们的代理方法会立即恢复保存的位置,用户不会感知到偏移变化。
方案2:保持WKWebView第一响应者并强制隐藏键盘(不推荐)
通过私有API可以直接隐藏键盘但保留第一响应者状态,但苹果审核大概率会拒绝,仅适合内部测试使用:
// Objective-C 私有API,谨慎使用 #import <UIKit/UIKit.h> @interface UIKeyboardImpl : NSObject + (instancetype)sharedInstance; - (void)dismissKeyboard; @end // 使用时调用 [[UIKeyboardImpl sharedInstance] dismissKeyboard];
额外提示
- 恢复偏移的时机优先选择
webViewDidBecomeFirstResponder,比监听scrollViewDidScroll更精准,避免不必要的滚动触发。 - 该方案不会影响contenteditable网页内的光标位置,仅恢复scrollView的外部滚动偏移,编辑状态完全保留。
内容的提问来源于stack exchange,提问作者jamBoomChuu
相关产品推荐
相关产品推荐

