如何在系统默认数字键盘上方显示透明视图?
解决iOS键盘始终在视图最上层的问题
这个困扰我也遇见过!iOS系统的键盘是在一个独立的UIWindow实例里渲染的,它的窗口层级比我们普通ViewController的view层级要高,所以不管你用bringSubviewToFront还是present新的VC,都没法让自己的视图盖在键盘上面。下面给你两个靠谱的解决方案:
方案一:将透明视图添加到键盘所在的窗口
我们可以监听键盘弹出的通知,找到键盘对应的窗口,然后把透明视图直接添加到这个窗口里,就能确保视图在键盘上方了:
// 先注册键盘弹出通知 NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidShowNotification, object: nil, queue: .main) { [weak self] notification in guard let self = self else { return } // 找到键盘对应的窗口(不同iOS版本类名可能不同,多兼容几个) guard let keyboardWindow = UIApplication.shared.windows.first(where: { $0.className == "UITextEffectsWindow" || $0.className == "UIRemoteKeyboardWindow" }) else { return } // 创建你的透明视图 let overlayView = UIView(frame: keyboardWindow.bounds) overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.3) // 示例透明度 overlayView.tag = 999 // 给个标记,方便后续键盘隐藏时移除 // 添加到键盘窗口并置顶 keyboardWindow.addSubview(overlayView) keyboardWindow.bringSubviewToFront(overlayView) } // 别忘了注册键盘隐藏通知,移除视图避免内存泄漏 NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidHideNotification, object: nil, queue: .main) { _ in guard let keyboardWindow = UIApplication.shared.windows.first(where: { $0.className == "UITextEffectsWindow" || $0.className == "UIRemoteKeyboardWindow" }) else { return } keyboardWindow.viewWithTag(999)?.removeFromSuperview() }
注意事项:不同iOS版本的键盘窗口类名可能会有变动,测试时要多覆盖几个系统版本;一定要在键盘隐藏时移除视图,防止内存泄漏。
方案二:创建层级更高的独立窗口
我们可以自己创建一个UIWindow,把它的窗口层级设得比键盘窗口更高,这样这个窗口里的视图就能覆盖键盘了:
// 创建新窗口,设置层级高于键盘(键盘一般用UIWindowLevelAlert级别) let overlayWindow = UIWindow(frame: UIScreen.main.bounds) overlayWindow.windowLevel = UIWindowLevelAlert + 1 overlayWindow.backgroundColor = .clear // 添加透明视图 let overlayView = UIView(frame: overlayWindow.bounds) overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.3) overlayWindow.addSubview(overlayView) // 显示窗口 overlayWindow.isHidden = false
拓展优化:如果只需要覆盖键盘区域,可以监听键盘的frame变化,动态调整overlayView的frame,避免遮挡其他内容。
两种方案里,更推荐方案一,因为它精准针对键盘窗口,不会影响屏幕其他区域的交互;方案二更适合需要全屏覆盖的场景。
内容的提问来源于stack exchange,提问作者user13133221
相关产品推荐
相关产品推荐

