iOS开发:如何实现除指定Stack View外全屏模糊(键盘适配场景)
问题
我想实现除指定Stack View外,整个屏幕都模糊的效果。当前App在键盘弹出时,Stack View里的文本输入框会上移,我还想给这个Stack View加个模糊背景。
我试了这段代码:
let blurEffect = UIBlurEffect(style: .prominent) blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.frame = view.bounds view.addSubview(blurEffectView)
但运行后连文本输入框也被模糊了。相关场景截图:
- App启动状态:

- 点击文本输入框后:

- 层级结构:

解决方案
要实现「除Stack View外全屏模糊+给Stack View加模糊背景」的效果,需从视图层级和模糊视图的添加方式两方面调整:
1. 实现全屏模糊(排除Stack View)
你当前的问题是把模糊视图直接加到最外层view上,覆盖了所有子视图(包括Stack View)。正确做法是将模糊视图放在Stack View的下方:
// 创建模糊视图 let blurEffect = UIBlurEffect(style: .prominent) let blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.frame = view.bounds // 适配屏幕旋转或尺寸变化 blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // 添加到view的最底层,让Stack View在它上方显示 view.insertSubview(blurEffectView, at: 0)
如果还有其他需要显示在模糊层上的元素,只需确保它们的视图层级高于模糊视图即可。
2. 给Stack View添加模糊背景
要给Stack View单独加模糊背景,需将模糊视图作为Stack View的子视图并放在最底层,同时设置Stack View背景透明:
// 创建Stack View的模糊背景,可选更柔和的模糊样式 let stackBlurEffect = UIBlurEffect(style: .systemUltraThinMaterial) let stackBlurView = UIVisualEffectView(effect: stackBlurEffect) stackBlurView.frame = stackView.bounds stackBlurView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // 把模糊背景加到Stack View的最底层 stackView.insertSubview(stackBlurView, at: 0) // 确保Stack View本身背景透明,让模糊背景显示出来 stackView.backgroundColor = .clear
3. 适配键盘弹出时的布局
键盘弹出时Stack View会上移,需监听键盘通知来更新模糊视图的frame:
// 在viewDidLoad中添加键盘通知监听 override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) } // 处理键盘尺寸变化的方法 @objc func keyboardWillChangeFrame(_ notification: Notification) { guard let userInfo = notification.userInfo, let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } let isKeyboardShowing = keyboardFrame.origin.y < view.bounds.height // 调整全屏模糊视图的frame if isKeyboardShowing { blurEffectView.frame = view.bounds.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: keyboardFrame.height, right: 0)) } else { blurEffectView.frame = view.bounds } // 确保Stack View的模糊背景始终贴合Stack View stackBlurView.frame = stackView.bounds }
内容的提问来源于stack exchange,提问作者Emir
相关产品推荐
相关产品推荐

