项目有个功能,向后台请求数据后如果有活动会在原有的TabbarController的Tabbar中间添加一个稍微大点的按钮,由四个Item变为五个,因为点击中间的按钮根据后台数据分为两种情况:一种相当于直接切换了TabbarController的index,另一种是先不切换index,在原来的ViewController上面Present出来一个半透明的蒙版,蒙版上面有两个Button,点击button后再切换index.效果如下:
所以想着将四个Item变为五个以后在中间添加一个按钮覆盖中间的TabBarItem,虽然功能已经实现了,但是中间的按钮并没有完全覆盖一个Item,所以如果点击到按钮周围还是有可能触发被覆盖的TabBarItem,不(钻)能(牛)容(角)忍(尖)!,然后在自己继承重写的TabbarController中设置一个属性判断是否是点击自定义的button触发的代理方法(centerBtnClicked:方法中设置了self.selectedIndex = 2,会触发代理方法 shouldSelectedViewController:),具体实现代码如下:
#import "YYFTabBarController.h"
#import "UIButton+WebCache.h"
#import "UIImageView+WebCache.h"
@interface YYFTabBarController ()<UITabBarControllerDelegate,UIGestureRecognizerDelegate>
{
BOOL _isCenterBtnPressed;
}
@property (strong, nonatomic) UITapGestureRecognizer *tap;
@property (strong, nonatomic) UIView *centerView;
@end
@implementation YYFTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = self;
// Do any additional setup after loading the view.
}
-(void)setShowCenterBtn:(BOOL)showCenterBtn{
if (showCenterBtn==YES) {
[self addCenterBtn];
}
_showCenterBtn = showCenterBtn;
}
//add center button
-(void)addCenterBtn{
self.centerView = [[UIView alloc] initWithFrame:CGRectMake((self.view.frame.size.width-60)/2, -(60-49)/2.0, 60.0f, 60.0f)];
self.centerView.backgroundColor = FANLITOU_RED_COLOR;
self.centerView.layer.cornerRadius = 30.0f;
UIImageView *menuLogo = [[UIImageView alloc]initWithFrame:CGRectMake(20, 15, 20, 20)];
[menuLogo sd_setImageWithURL:[NSURL URLWithString:self.activityDic[@"menu_logo"]]];
UILabel *menuName = [[UILabel alloc]initWithFrame:CGRectMake(0, 37, 60, 20)];
menuName.textAlignment = NSTextAlignmentCenter;
menuName.text = self.activityDic[@"menu_name"];
menuName.font = [UIFont systemFontOfSize:10];
menuName.textColor = [UIColor whiteColor];
[ self.centerView addSubview:menuLogo];
[ self.centerView addSubview:menuName];
self.tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(centerBtnClicked:)];
self.tap.delegate = self;
//add tap gesture
[ self.centerView addGestureRecognizer:self.tap];
[self.tabBar addSubview: self.centerView];
}
-(void)centerBtnClicked:(UITapGestureRecognizer *)tap{
NSLog(@"centerBtnPressed");
if ([self.activityDic[@"menu_type"] isEqualToString:@"single"]) {
NSLog(@"showActivity");
//is center button pressed
_isCenterBtnPressed = YES;
self.selectedIndex = 2;
}
}
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
NSLog(@"clicked");
//!!!!!!!!!!!!!!!!!!!!!!!!!! 没有这个方法的话 切换tabbar中间按钮点击事件会被tabbar覆盖
[self.tabBar bringSubviewToFront:self.centerView];
if (self.showCenterBtn&&(viewController == tabBarController.viewControllers[2])) {
NSLog(@"clicked3");
//if is center button pressed ,return yes, select index 2
if (_isCenterBtnPressed) {
//reset to NO
_isCenterBtnPressed = NO;
return YES;
}
return NO;
}
return YES;
}
@end
一个很头疼的问题,添加过按钮后第一次点击中间的按钮会触发按钮的事件,但是切换过index后再点击按钮后触发的就是被按钮覆盖了的那个位置的Item的点击事件,也就是直接切换了控制器。想着应该是手势冲突了,然后各种百度,Google,文档都没有解决问题最后想了想既然第一次点击按钮会触发它的点击事件,切换过以后点击事件就被覆盖了,和View的层级何其相似,虽然不知道tabbar点击做了什么处理,但是这不影响我天马星空般的思维,没错!就是在代理方法中添加了这一句代码:
[self.tabBar bringSubviewToFront:self.centerView];
然后世界都变成彩色的了……