Swift中UITabBar上方CollectionView触摸失效问题求助
UITabBar上方CollectionView无法响应触摸的问题修复
问题描述
在UITabBar上方添加了包含CollectionView的quickAccessView,但该CollectionView无法响应触摸操作。
原始实现代码
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() self.tabBar.bringSubviewToFront(quickAccessView) } private func setupQuickAccessView(){ print("this is tabBar's height", self.tabBar.frame.size.height) self.tabBar.frame.size.height = 150 print("this is new tabBar's height", self.tabBar.frame.size.height) self.tabBar.addSubview(quickAccessView) quickAccessView.clipsToBounds = true } private func addQuickAccessViewConstraints(){ quickAccessView.snp.makeConstraints { make in make.right.left.equalTo(self.tabBar.safeAreaLayoutGuide) make.height.equalTo(76) make.bottom.equalTo(self.tabBar.snp.bottom).offset(-80) } }
修改后的代码及存在的问题
UITabBarController部分
强制将tabBar转换为QuickAccessSupportedTabBar时崩溃,且viewDidAppear中错误修改了主视图frame:
final class MainTabBarController: UITabBarController { private lazy var quickAccessView: QuickAccessView = .fromNib() var quickAccessSupportedTabBar: QuickAccessSupportedTabBar { self.tabBar as! QuickAccessSupportedTabBar // 此处崩溃 } override func viewDidLoad() { super.viewDidLoad() self.tabBar.backgroundColor = .white } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.view.frame = self.quickAccessView.bounds // 错误设置 setupUI() } } extension MainTabBarController{ private func setupUI(){ setupQuickAcessView() addQuickAcessViewConstraints() } } // MARK: - Setting Up Quick Access view extension MainTabBarController { private func setupQuickAcessView(){ self.quickAccessSupportedTabBar.addSubview(quickAccessView) } private func addQuickAcessViewConstraints(){ quickAccessView.snp.makeConstraints { make in make.left.right.equalTo(self.quickAccessSupportedTabBar.safeAreaLayoutGuide) make.height.equalTo(66) make.bottom.equalTo(self.quickAccessSupportedTabBar.snp.top) } } }
自定义UITabBar部分
无法访问quickAccessView,坐标转换逻辑有误:
class QuickAccessSupportedTabBar: UITabBar { override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if !quickAccessView.isHidden { // 无法访问quickAccessView let targetPoint = quickAccessView.convert(point, from: self) // 坐标转换方向错误 if quickAccessView.bounds.contains(targetPoint) { return quickAccessView.hitTest(targetPoint, with: event) } } return super.hitTest(point, with: event) } }
解决方案
1. 修复TabBar类型转换崩溃
确保TabBarController的tabBar确实是自定义的QuickAccessSupportedTabBar类型:
- 代码初始化方式:在
viewDidLoad中替换默认TabBar
override func viewDidLoad() { super.viewDidLoad() self.tabBar = QuickAccessSupportedTabBar() self.tabBar.backgroundColor = .white }
- Storyboard方式:选中TabBar组件,在Identity Inspector中将Class设置为
QuickAccessSupportedTabBar。
2. 让自定义TabBar能访问quickAccessView并修正触摸检测逻辑
修改自定义TabBar,添加属性持有quickAccessView引用,并修正坐标转换:
class QuickAccessSupportedTabBar: UITabBar { weak var quickAccessView: UIView? // 使用weak避免循环引用 override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { guard let quickAccessView = quickAccessView, !quickAccessView.isHidden else { return super.hitTest(point, with: event) } // 将TabBar坐标系的点转换为quickAccessView的坐标系 let targetPoint = convert(point, to: quickAccessView) if quickAccessView.bounds.contains(targetPoint) { return quickAccessView.hitTest(targetPoint, with: event) } return super.hitTest(point, with: event) } }
3. 修正TabBarController中的错误代码
移除viewDidAppear中错误的frame设置,并传递quickAccessView引用给自定义TabBar:
final class MainTabBarController: UITabBarController { private lazy var quickAccessView: QuickAccessView = .fromNib() var quickAccessSupportedTabBar: QuickAccessSupportedTabBar { guard let tabBar = self.tabBar as? QuickAccessSupportedTabBar else { fatalError("TabBar must be of type QuickAccessSupportedTabBar") } return tabBar } override func viewDidLoad() { super.viewDidLoad() self.tabBar.backgroundColor = .white setupUI() // 移到viewDidLoad中执行 } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 移除错误的frame设置代码 } } extension MainTabBarController{ private func setupUI(){ setupQuickAcessView() addQuickAcessViewConstraints() } } // MARK: - Setting Up Quick Access view extension MainTabBarController { private func setupQuickAcessView(){ self.quickAccessSupportedTabBar.addSubview(quickAccessView) // 传递quickAccessView引用给自定义TabBar self.quickAccessSupportedTabBar.quickAccessView = quickAccessView } private func addQuickAcessViewConstraints(){ quickAccessView.snp.makeConstraints { make in make.left.right.equalTo(self.quickAccessSupportedTabBar) make.height.equalTo(66) make.bottom.equalTo(self.quickAccessSupportedTabBar.snp.top) } } }
4. 规范TabBar高度修改方式
避免直接修改tabBar.frame.size.height,可在自定义TabBar中重写intrinsicContentSize:
class QuickAccessSupportedTabBar: UITabBar { override var intrinsicContentSize: CGSize { return CGSize(width: super.intrinsicContentSize.width, height: 150) // 自定义高度 } }
内容的提问来源于stack exchange,提问作者Rohan Dalmotra
相关产品推荐
相关产品推荐

