You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MDCBottomSheetController软键盘避免上推视图问题求助

解决MDCBottomSheetController被键盘上推的问题

我之前在使用MDCBottomSheetController时也碰到过完全一样的问题——弹出软键盘时整个底部表单被向上顶,直接打乱了原本的布局。这里有几个简单有效的解决方案,你可以按需尝试:

方案1:直接禁用MDCBottomSheet的键盘自动适配

MDCBottomSheetController本身封装了键盘处理的配置项,你只需要在present表单前添加一行代码,把键盘处理模式设为.none,就能彻底阻止它被键盘上推:

let bottomSheet: MDCBottomSheetController = MDCBottomSheetController(contentViewController: viewController)
// 添加这行代码禁用键盘自动适配
bottomSheet.keyboardHandlingMode = .none
// 你的原有配置代码保持不变
bottomSheet.shouldFlashScrollIndicatorsOnAppearance = true
if openFor == SearchBottomSheetViewController.OPEN_FOR_DATE {
    bottomSheet.preferredContentSize = CGSize(width: self.view.frame.size.width, height: self.view.frame.size.height * 0.3)
}else {
    bottomSheet.preferredContentSize = CGSize(width: self.view.frame.size.width, height: 3 * self.view.frame.size.height / 4)
}
present(bottomSheet, animated: true, completion: nil)

这个方案是最推荐的,因为它是Material Components官方提供的原生控制逻辑,不需要额外处理复杂的键盘通知。

方案2:调整内容控制器的滚动视图适配(针对含滚动视图的表单)

如果你的底部表单内容里包含UIScrollView(比如UITableView、UICollectionView这类子类),可以设置滚动视图的内边距调整行为为.never,让它不会自动适配键盘:

// 在你的contentViewController的viewDidLoad方法中添加
if let scrollView = view.subviews.first(where: { $0 is UIScrollView }) as? UIScrollView {
    scrollView.contentInsetAdjustmentBehavior = .never
}

这个方案适合你需要保留底部表单其他交互行为,但单独让滚动视图不受键盘影响的场景。

方案3:手动监听键盘通知强制固定表单尺寸(兜底方案)

如果上面两个方案都不生效,你可以手动监听键盘的弹出/收起通知,强制把表单尺寸固定为你想要的大小:

// 在present底部表单前添加通知监听
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

// 实现监听方法
@objc func keyboardWillChangeFrame(_ notification: Notification) {
    guard let bottomSheet = presentedViewController as? MDCBottomSheetController else { return }
    // 强制设置回你原本定义的尺寸
    if openFor == SearchBottomSheetViewController.OPEN_FOR_DATE {
        bottomSheet.preferredContentSize = CGSize(width: self.view.frame.size.width, height: self.view.frame.size.height * 0.3)
    }else {
        bottomSheet.preferredContentSize = CGSize(width: self.view.frame.size.width, height: 3 * self.view.frame.size.height / 4)
    }
}

// 记得在页面销毁时移除监听
deinit {
    NotificationCenter.default.removeObserver(self)
}

这个方案相对繁琐,但能确保在极端情况下表单尺寸不会被键盘篡改。

优先推荐方案1,简洁又可靠,完全匹配你的需求场景。

内容的提问来源于stack exchange,提问作者amodkanthe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:16:46