很多项目中使用TabBarController的时候, 系统自带的TabBar不满足需求,因此需要自定义tabBar的视图.
如果你是用UIButton自定义的话,恭喜你没有问题.事件正常响应.
如果你是用View自定义稍微复杂点的视图,比如View上加一个徽章,这个VIew竟然不能响应事件,明明看到自定义的View正常显示在指定位置,怎么就不能响应,给了背景色,竟然也不能显示背景色,我靠,然后你会在网上一顿乱搜索,发现都是在说隐藏TabBar来自定义的这种比较low的方法,需要在视图将要显示的viewWillAppear上加一句addSubview.那KVC实现自定义TarBar时,也不响应怎么办?你会一脸懵逼.
你这个时候你一定在考虑响应者链问题吧? 确保View都是可以交互时,还是不行,你又一脸懵逼.
你这时候又会想到,难道是像网上说的那样隐藏TabBar方式自定义,tabBar.subviews中没有自定义的View,需要手动添加一下addSubview?但是咱们用KVC更屌的方法,在控制器中addSubview,显然不合适,也行不通.你是不是一脸懵逼的再想:我曹,这TM的Xcode就是傻X.
这时候,你老老实实在继承UITabBar的自定义类layoutSubviews中打印subviews,你看到下面的打印结果,你TM的又想吃键盘了!
<UITabBarButton: 0x7fa032d0ccb0; frame = (2 1; 121 48); opaque = NO; layer = <CALayer: 0x600000427b00>>
<UITabBarButton: 0x7fa032c13cc0; frame = (127 1; 121 48); opaque = NO; layer = <CALayer: 0x600000428260>>
<UITabBarButton: 0x7fa032d17480; frame = (252 1; 121 48); opaque = NO; layer = <CALayer: 0x600000428740>>
<ZHTest.ZHRedHotView: 0x7fa032c0b2c0; frame = (187.5 24.5; 93.75 0); autoresize = RM+BM; gestureRecognizers = <NSArray: 0x60000004e7c0>; layer = <CALayer: 0x600000422040>>
- frame的宽度有,竟然没高度??那为什么View的内容还能正常显示?明明我懒加载时,给了bounds.话说回来,没有高度,你点哪?所以解决高度就OK了.
lazy var redView : ZHRedHotView = {
let redView = ZHRedHotView.redHotView()
redView.bounds = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width / 4, height: self.bounds.height)
return redView
}()
- 这时候,你豁然开朗,给出了解决方案,不要在懒加载中指定frame,改为在layoutSubviews中指定frame.并愉快的在简书上写下了这个坑.然后午睡......
override func layoutSubviews() {
super.layoutSubviews()
//遍历子视图,添加中间的Button
let width = UIScreen.main.bounds.width / 4
let height = self.bounds.height
var index = 0
for sub in subviews{
print(sub)
//判断如果是UITabBarButton类型才继续
if sub.isKind(of: NSClassFromString("UITabBarButton")!) {
sub.frame = CGRect(x: CGFloat(index) * width, y: 0, width: width, height: height)
index += (index == 1 ? 2 : 1)
}
}
redView.center = CGPoint(x: self.center.x + width * 0.5, y: height * 0.5)
redView.bounds = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width / 4, height: self.bounds.height)
}