【已解决】Swift 隐藏tabBar后下方的button不可点击

本文介绍了在Swift项目中使用UISearchController时遇到的问题:隐藏tabBar后,下方的button无法点击。作者通过分析原因,发现是由于view层级关系导致的点击范围问题。解决方案包括在显示resultVC时调整父控件view的frame,以及在恢复时恢复frame,同时适配刘海屏的homeIndicator。最终实现了按钮的正常点击。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中用到UISearchController,点击后需要显示SearchResultController,并且把tabBar隐藏,做完后发现即使tabBar隐藏了,原先位置下的button不可点击。网上的帖子都在复制粘贴,实在是效率太低,并且没什么作用,所以只能自己琢磨了。

嫌麻烦的兄弟可以直接看下方的 解决办法

前言

网上隐藏tabBar的方法大致总结为:修改frame、移动位置、设置alpha和直接设置hidden,这些方法都可以隐藏,但是都不可点击下方的控件。

发现问题

而不可点击控件的原因大致总结为:有遮盖物在上面、控件本身或父控件的user Interaction Enabled为false、控件本身的点击范围不在父控件范围内,所以问题找到了,肯定是最后一种原因导致的。

运行项目后用Xcode调试工具看看view层级关系,果然是这个原因,可以看到虽然隐藏了tabBar,并且把resultVC的tableViewInset设置了,但是父类的view没有更改,导致不可点击。

不可点击

解决办法

思路

  1. 当显示resultVC时设置父控件view的frame,在恢复的时候也把frame恢复
  2. 在resultVC里设置view的frame,并且设置tableView的contentInset适配刘海屏

上代码

  1. 先把公用方法放这
// MARK:- Method

func isiPhoneX() ->Bool {
    let safeAreaBottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom
    return safeAreaBottom == 0 ? false : true
}

// MARK:- Common
let ScreenWidth = UIScreen.main.bounds.size.width
let ScreenHeight = UIScreen.main.bounds.size.height
let HomeIndicatorHeight: CGFloat = isiPhoneX() ? 34 : 0
let TabBarHeight: CGFloat = isiPhoneX() ? 49+34 : 49
  1. 在searchControllerDelegate的代理方法中设置父控件view的frame,设置需要tabBar高度+homeIndicator的高度

更新 最好在控制器内定义私有属性,在改变frame之前,用属性记录高度,然后在下面准备消失时直接赋值,因为在iOS 13机器上,可能切换前后台绘制页面会有问题…页面被重复修改

// MARK:- UISearchControllerDelegate

extension WBHomeViewController: UISearchControllerDelegate {
    // 准备显示
    func willPresentSearchController(_ searchController: UISearchController) {
    	// 改变frame之前记录高度
    	self.originViewHeight = self.view.frame.size.height
        self.tabBarController?.tabBar.isHidden = true
        self.view.frame.size.height += TabBarHeight
    }
    
    // 准备消失
    func willDismissSearchController(_ searchController: UISearchController) {
        self.tabBarController?.tabBar.isHidden = false
        // self.view.frame.size.height -= TabBarHeight
        // 直接赋值
       	self.view.frame.size.height = self.originViewHeight
    }
}
  1. 父类的view设置完后,可以发现子类的view因为homeIndicator的关系显示有问题,所以设置子类的view的frame,因为父类已经设置了tabBar的高度,所以子类只需要设置homeIndicator的高度,在vc的生命周期方法里设置
override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.view.frame.size.height += HomeIndicatorHeight
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.view.frame.size.height -= HomeIndicatorHeight
    }
  1. 至此应该点击没有问题了,现在开始适配刘海屏的homeIndicator,让tableView全屏显示(否则小横条位置是遮住的),设置tableView的contentInset
// 用两倍的高度是因为需要显示在小横条上方,如果设置1倍高度,最后内容会在小横条位置,点击会有误操作,而且用户观感不好,可以debug看看效果
self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 2*HomeIndicatorHeight, right: 0)

最后改完的效果:

改完后的效果


欢迎大家访问我的主页:

优快云:优快云
知乎:知乎
微博:微博

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值