最近被 iOS 模拟器
摆了一道. 真的是坑.
项目中需要一个这样的位于页面 底部的Bar
效果如图:
需求中需要 3 个 item
的 bar
, 并且需要向下做 平移动画
达到 隐藏
和 出现
的效果.
于是选择了自己封装.
视图结构入下:
1
2
UIView
|- UITabBar
此处之所以选择 UITabBar
而没有选择 UIToolBar
是因为 UITabBar
一直是我们非常熟悉的一个 UI控件
, 但是我从来未单独的使用过(一直直接使用UITabBarController
), 因此此处就作为尝试, 选择了 UITabBar
.
一切都非常顺利的封装完成, 并且在 模拟器
上效果如上效果图所示, 即为 模拟器
实际效果的截图.
但是在真机上却并未达到预期效果, 截图如下:
出现这个情况的原因是因为 UITabBar
的内容被挤压了.
黑色的部分为 UITabBar
但是作为载体的父视图 frame
是正常的 49 + safeArea.bottom
.
看一下我的约束:
1
2
3
4
5
6
7
- (void)setupUI {
self.alpha = 0.85f;
[self addSubview:self.tabbar];
[_tabbar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.mas_equalTo(0.0f);
}];
}
此处仅仅对 _tabbar
的 left
, right
和 top
做了约束是因为 UITabbar
其有自身的默认高度, 我们只需让父视图的 高度
合适, UITabbar
只需自己调整 高度
即可. 在 模拟器
上面的确达到了我预想的效果.
然而在 真机
上却出现了 UITabbar
内部被挤压的情况.
这个显然是 UITabbar
的 BUG
. 之所以说是 BUG
是因为造成这个问题的原因是这样的:
我们知道, 在 刘海屏
上的时候 UITabBar
会自动的调整 高度
, 同时其 title
和 image
都会被向上移动, 来防止 item
被 遮挡
.
但是, 在 UITabbar
的 safeArea.bottom == 0
的时候, 显然是 frame
并未做调整, 但是内容却被 挤压
了. 因此造成了这种结果.
解决方法:
1
2
3
4
- (void)layoutSubviews {
[super layoutSubviews];
_tabbar.frame = self.bounds;
}
这样的话, 因为我们的 容器视图
的 frame
就是计算出的正确的信息, 那就让 UITabBar
直接平铺满我们的整个 容器视图
好了.
当然, 使用 Masonry
约束也可以, 但是因为上篇: 记一次 UICollectionView 卡顿掉帧的问题 中由于 自动布局
的性能问题, 给我的项目造成了一些 BUG
, 因此既然是要 占满
我们的 容器视图
, 直接在 layoutSubviews
里面来进行布局计算好了.
虽然这个问题的确不是什么常见问题, 但是还是需要做个总结来加深一下印象, 如果有遇到同样问题的同学, 也可以加快下解决问题的速度.
此外, 模拟器
也并非是 100%
的与 真机
效果同步, 因此最终还是 要以真机效果为准
.