在項(xiàng)目過(guò)程中褪那,經(jīng)常遇到系統(tǒng)原生的UITabBar無(wú)法滿足我們的需求艳吠,這時(shí)候就難免需要我們自己根據(jù)需求去自定義一個(gè)tabBar了
先看一下最后的效果圖:
以下自定義是實(shí)現(xiàn)代碼:
DBHTabBar.h:
#import <UIKit/UIKit.h>
@class DBHTabBar;
@protocol DBHTabBarDelegate <UITabBarDelegate>
@optional
- (void)tabBarDidClickPlusButton:(DBHTabBar *)tabBar;
@end
@interface DBHTabBar : UITabBar
@property (nonatomic, weak) id<DBHTabBarDelegate> myDelegate;
@end
DBHTabBar.m
#import "DBHTabBar.h"
@interface DBHTabBar ()
@property (nonatomic, strong) UIButton *plusButton;
@end
@implementation DBHTabBar
#pragma mark - Lifecycle
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addSubview:self.plusButton];
}
return self;
}
#pragma mark - Event Responds
/**
* 點(diǎn)擊了加號(hào)按鈕
*/
- (void)respondsToPlusButton
{
// 通知代理
if ([self.delegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
[self.myDelegate tabBarDidClickPlusButton:self];
}
}
#pragma mark - Private Methods
/**
* 重新布局系統(tǒng)tabBarItem
*/
- (void)layoutSubviews
{
[super layoutSubviews];
// 1.設(shè)置加號(hào)按鈕的位置
self.plusButton.center = CGPointMake(CGRectGetWidth(self.frame) * 0.5, CGRectGetHeight(self.frame) * 0.1);
// 2.設(shè)置其他tabbarButton的frame
CGFloat tabBarButtonWidth = CGRectGetWidth(self.frame) / 5;
CGFloat tabBarButtonIndex = 0;
for (UIView *childView in self.subviews) {
Class class = NSClassFromString(@"UITabBarButton");
if ([childView isKindOfClass:class]) {
// 設(shè)置位置
childView.frame = CGRectMake(tabBarButtonWidth * tabBarButtonIndex, CGRectGetMinY(childView.frame), tabBarButtonWidth, CGRectGetHeight(childView.frame));
// 增加索引
tabBarButtonIndex += (tabBarButtonIndex == 1 ? 2 : 1);
}
}
}
/**
重寫(xiě)hitTest方法以響應(yīng)點(diǎn)擊超出tabBar的加號(hào)按鈕
*/
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (!self.clipsToBounds && !self.hidden && self.alpha > 0) {
UIView *result = [super hitTest:point withEvent:event];
if (result) {
return result;
}
else {
for (UIView *subview in self.subviews.reverseObjectEnumerator) {
CGPoint subPoint = [subview convertPoint:point fromView:self];
result = [subview hitTest:subPoint withEvent:event];
if (result) {
return result;
}
}
}
}
return nil;
}
#pragma mark - Getters And Setters
- (UIButton *)plusButton {
if (!_plusButton) {
_plusButton = [[UIButton alloc] init];
[_plusButton setImage:[UIImage imageNamed:@"plusButton"] forState:UIControlStateNormal];
[_plusButton setImage:[UIImage imageNamed:@"plusButton_selected"] forState:UIControlStateHighlighted];
_plusButton.frame = CGRectMake(0, 0, _plusButton.imageView.image.size.width, _plusButton.imageView.image.size.height);
[_plusButton addTarget:self action:@selector(respondsToPlusButton) forControlEvents:UIControlEventTouchUpInside];
}
return _plusButton;
}
@end
使用的2個(gè)步驟方法:
1?在UITabBarController中新建一個(gè)tabBar并替換掉原有的tabBar
DBHTabBar *tabBar = [[DBHTabBar alloc] init];
//取消tabBar的透明效果
tabBar.translucent = NO;
// 設(shè)置tabBar的代理
tabBar.myDelegate = self;
// KVC:如果要修系統(tǒng)的某些屬性养渴,但被設(shè)為readOnly,就是用KVC绳军,即setValue:forKey:五督。
[self setValue:tabBar forKey:@"tabBar"];
2?實(shí)現(xiàn)剛才自定義的tabBar中寫(xiě)的協(xié)議
/**
* 點(diǎn)擊了加號(hào)按鈕
*/
- (void)tabBarDidClickPlusButton:(DBHTabBar *)tabBar
{
// 在這里寫(xiě)你點(diǎn)擊加號(hào)按鈕需要做的操作,我這里是彈出一個(gè)提示框
UIAlertController *promptAlert = [UIAlertController alertControllerWithTitle:@"提示" message:@"點(diǎn)擊了加號(hào)按鈕" preferredStyle:UIAlertControllerStyleAlert];
[promptAlert addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:promptAlert animated:YES completion:nil];
}
友情提示:當(dāng)加號(hào)按鈕超出tabBar時(shí),點(diǎn)擊超出的那一部分按鈕事件將不會(huì)響應(yīng)敲茄。不過(guò)位谋,只需要重寫(xiě)tabBar中hitTest方法即可解決哦,重寫(xiě)方式已經(jīng)在代碼中貼出來(lái)了哦堰燎。
到此掏父,就結(jié)束了,第一次嘗試寫(xiě)博客秆剪,寫(xiě)的不清楚之處還望諒解赊淑。
Demo地址