1. 属性translucent
- UINavigationController -> UINavigationBar -> translucent
- UITabBarController -> UITabBar -> translucent
A Boolean value indicating whether the navigation bar is translucent (YES) or not (NO).
一个布尔值,指示导航栏是否为半透明(是)或非半透明(否)。
默认为YES,自动布局时,导航栏、标签栏遮挡subvc.view视图
UINavigationController *navVC;
nav.navigationBar.translucent = NO;
UITabBarController *tabBarVC;
MyTabBar *tabbar = [MyTabBar new];
tabbar.tintColor = [UIColor redColor];// 设置tabBarItem选中状态时的颜色
[tabBarVC setValue:tabbar forKey:@"tabBar"];// 利用KVO来使用自定义的tabBar
tabBarVC.tabBar.translucent = NO; // KVO设置后,设置改属性为NO
2. 自定义UITabBar
通过自定义UITabBar,重写layoutSubviews方法,修改UI布局,可以实现想要的功能。
当设置标签栏子控制器的title时,会触发UITabBar的layoutSubviews方法,此时subiews中UITabBarButton顺序变动,不能按获取数组索引操作UITabBarButton的frame,否侧会导致标签栏控制器错序,所以必须以frame.origin.x升序排序后操作。
// 重新布局tabBarItem(这里需要具体情况具体分析,本例是中间有个按钮,两边平均分配按钮)
- (void)layoutSubviews
{
[super layoutSubviews];
// 把tabBarButton取出来(把tabBar的SubViews打印出来就明白了)
NSMutableArray *tabBarButtonArray = [NSMutableArray array];
for (UIView *view in self.subviews) {
if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
[tabBarButtonArray addObject:view];
}
}
/**
因为标签栏tabbar layoutSubviews 后更新某个标签栏子控制器的title时,会更新该标签栏对应位置的标题,
即会触发layoutSubviews,并且最新更新title的子控制器在数组的低索引位置;
而下列按数组顺序更新frame,会导致错乱;
所以必须以fram.x 升序排序后再更新frame。
控制器vc的标题:
@property(nullable, nonatomic,copy) NSString *title;
@Summary:A localized string that represents the view this controller manages.
@Discussion:Set the title to a human-readable string that describes the view.
【重点说明】If the view controller has a valid navigation item or tab-bar item,
assigning a value to this property updates the title text of those objects.
*/
NSArray *sortOriginXArr = [tabBarButtonArray sortedArrayUsingComparator:^NSComparisonResult(UIView * _Nonnull obj1, UIView * _Nonnull obj2) {
return obj1.frame.origin.x < obj2.frame.origin.x ? NSOrderedAscending : NSOrderedDescending;
}];
CGFloat barWidth = self.bounds.size.width;
CGFloat barHeight = self.bounds.size.height;
CGFloat centerBtnWidth = CGRectGetWidth(self.centerBtn.frame);
CGFloat centerBtnHeight = CGRectGetHeight(self.centerBtn.frame);
// 设置中间按钮的位置,居中,凸起一丢丢
self.centerBtn.center = CGPointMake(barWidth / 2, barHeight - centerBtnHeight/2 - 5);
// 重新布局其他tabBarItem
// 平均分配其他tabBarItem的宽度
CGFloat barItemWidth = (barWidth - centerBtnWidth) / sortOriginXArr.count;
// 逐个布局tabBarItem,修改UITabBarButton的frame
[sortOriginXArr enumerateObjectsUsingBlock:^(UIView * _Nonnull view, NSUInteger idx, BOOL * _Nonnull stop) {
CGRect frame = view.frame;
if (idx >= sortOriginXArr.count / 2) {
// 重新设置x坐标,如果排在中间按钮的右边需要加上中间按钮的宽度
frame.origin.x = idx * barItemWidth + centerBtnWidth;
} else {
frame.origin.x = idx * barItemWidth;
}
// 重新设置宽度
frame.size.width = barItemWidth;
view.frame = frame;
}];
// 把中间按钮带到视图最前面
[self bringSubviewToFront:self.centerBtn];
}