前期开发项目刚好UI给了这么个设计,看了挺多实现方案,发现普遍较为复杂或凸起部分无法正常点击,废话不多说,让我们看看怎么再不重新定义中间Item的情况下用简单的方式在系统给定变量的基础上实现TabBar凸起的设计
在UI效果上实现Tabbar凸起
这里牵扯到三个属性titlePositionAdjustment、imageInsets、masksToBounds
-
masksToBounds
首先设置tabBar.layer.masksToBounds = NO
,保证tabBar上的item可以超出原有的矩形范围 -
imageInsets、titlePositionAdjustment
调整你想要凸起的那个item的文字及图片位置
naviController.tabBarItem.image = [[UIImage imageNamed:@"tabbar_measure_nomal.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
naviController.tabBarItem.imageInsets = UIEdgeInsetsMake(-13, 0, 13, 0);//注意这个-13和13这两个值要一至,保证上移且图片不被拉伸
naviController.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -2);
naviController.tabBarItem.title = LocalString(@"Tabbar_Measure");
触摸范围的调整
继承UITabBar,重写- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
方法
@implementation MGCTabBar
- (instancetype)init
{
if (self = [super init]) {
self.layer.masksToBounds = NO;
self.tintColor = RGB(0x32, 0xc5, 0xd2);
}
return self;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if (!self.hidden) {
CGFloat r = 25;
CGPoint center = CGPointMake(D_Screen_Width / 2.0, r - 15);
if (point.y < 0 && (center.x - point.x) * (center.x - point.x) + (center.y - point.y) * (center.y - point.y) < r * r) {
return [super hitTest:CGPointMake(D_Screen_Width / 2.0, 10) withEvent:event];
} else {
return [super hitTest:point withEvent:event];
}
}
return [super hitTest:point withEvent:event];
}
@end
应用重写的MGCTabBar
继承UITabBarController、替换系统tabBar
@implementation MGCTabBarController
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupUI];
}
- (void)setupUI
{
MGCTabBar *tabBar = [[MGCTabBar alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[self setValue:tabBar forKeyPath:@"tabBar"];
self.tabBar.tintColor = RGB(0x32, 0xc5, 0xd2);
self.selectedIndex = 0;
}
@end
点击时响应
完成前边几步,已经实现了TabBar凸起效果,下边我们看看如何在点击中间按钮时弹出你期望的页面
-
如果你的APP类似于“Metro大都会”中间凸起的“乘车item“除了凸起外和其他四个item没什么区别,那么完成上边几步后你无需做其他处理。
-
如果你的APP类似于“微博”,点击中间按钮弹出的是新的页面,取消后选中的需要是之前选中的item(点击”+“之前选中的item是“发现”,取消弹出页面后选中的item依然是“发现”)那么你还需要监听凸起item的点击事件
在AppDelegate方法中实现UITabBarControllerDelegate的方法- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
NSInteger index = [tabBarController.viewControllers indexOfObject:viewController];
if (index == 2) { //当点击中间凸起item时弹出你希望弹出的页面,如果你弹出的页面可能还有二级及二级以上页面,你可以把它作为naviController的RootViewController弹出
MGCMeasurePWViewController *measureVC = [[UIStoryboard storyboardWithName:@"Two" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"MGCMeasurePWViewController"];
MGCNavigationController *naviController = [[MGCNavigationController alloc] initWithRootViewController:measureVC];
naviController.navigationBar.hidden = YES;
[tabBarController presentViewController:naviController animated:YES completion:nil];
}
return index != 2;
}
到这我们就实现了tabBar凸起的效果,如有疑问欢迎提出,如有更好的方案欢迎赐教