自定义TabBar以及TabBar上的TabBarButton可以实现自动切换

来源:互联网 发布:大q吧数据 编辑:程序博客网 时间:2024/05/17 20:28

//

//  ZZTabBarButton.h

//  ZZ_APP主流框架

//

//  Created by ZZ_Macpro on 15/9/25.

//  Copyright (c) 2015 ZZ_Macpro. All rights reserved.

//


#import <UIKit/UIKit.h>


@interface ZZTabBarButton :UIButton

/**

 *  tabbar 上面的子控件只能是UITabBarItem

 */

@property (nonatomic,weak) UITabBarItem *item;

@end



//

//  ZZTabBarButton.m

//  ZZ_APP主流框架

//

//  Created by ZZ_Macpro on 15/9/25.

//  Copyright (c) 2015 ZZ_Macpro. All rights reserved.

//


// 图标的比例

#define ZZTabBarButtonImageRatio 0.65


#import "ZZTabBarButton.h"

#import "ZZBadgeButton.h"


constdouble ZZTabBarImageRatio = 0.65;


#define ZZTabBarButtonTitleColor (iOS7 ? [UIColor blackColor] : [UIColor whiteColor])

#define ZZTabBarButtonTitleSelectedColor (iOS7 ? ZZColor(236,103, 0) : ZZColor(253,163, 25))


@interface ZZTabBarButton()

@property (weak, nonatomic) ZZBadgeButton *badgeButton;

@end


@implementation ZZTabBarButton


- (id)initWithFrame:(CGRect)frame

{

   self = [superinitWithFrame:frame];

   if (self) {

        // 1.图片居中

        self.imageView.contentMode =UIViewContentModeCenter;

        

        // 2.文字居中

        self.titleLabel.textAlignment =NSTextAlignmentCenter;

        self.titleLabel.font = [UIFontsystemFontOfSize:11];

        [selfsetTitleColor:ZZTabBarButtonTitleSelectedColorforState:UIControlStateSelected];

        [selfsetTitleColor:ZZTabBarButtonTitleColorforState:UIControlStateNormal];

        

        // 3.设置选中时的背景图片

       if (!iOS7) {

            [selfsetBackgroundImage:[UIImageresizedImageWithName:@"tabbar_slider"]forState:UIControlStateSelected];

        }

        

        // 4.添加一个显示红色提醒数字的按钮

        [selfsetupBadgeButton];

    }

    return self;

}


- (void)setupBadgeButton

{

   ZZBadgeButton *badgeButton = [[ZZBadgeButtonalloc] init];

    badgeButton.autoresizingMask =UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;

    [selfaddSubview:badgeButton];

   self.badgeButton = badgeButton;

}


/**

 *  目的是去掉父类在高亮时所做的操作

 */

- (void)setHighlighted:(BOOL)highlighted {}


#pragma mark - 覆盖父类的2个方法

#pragma mark 设置按钮标题的frame

- (CGRect)titleRectForContentRect:(CGRect)contentRect {

   CGFloat titleY = contentRect.size.height *ZZTabBarImageRatio;

   CGFloat titleH = contentRect.size.height - titleY;

   CGFloat titleW = contentRect.size.width;

   return CGRectMake(0, titleY, titleW,  titleH);

}


#pragma mark 设置按钮图片的frame

- (CGRect)imageRectForContentRect:(CGRect)contentRect {

   CGFloat imageH = contentRect.size.height *ZZTabBarImageRatio;

   CGFloat imageW = contentRect.size.width;

   return CGRectMake(0,0, imageW,  imageH);

}


- (void)setItem:(UITabBarItem *)item

{

   _item = item;

    

    // 1.利用KVO监听item属性值的改变

    [item addObserver:selfforKeyPath:@"title"options:NSKeyValueObservingOptionNewcontext:nil];

    [item addObserver:selfforKeyPath:@"image"options:NSKeyValueObservingOptionNewcontext:nil];

    [item addObserver:selfforKeyPath:@"selectedImage"options:NSKeyValueObservingOptionNewcontext:nil];

    [item addObserver:selfforKeyPath:@"badgeValue"options:NSKeyValueObservingOptionNewcontext:nil];

    

    // 2.属性赋值

    [selfobserveValueForKeyPath:nilofObject:nilchange:nilcontext:nil];

}


/**

 *  KVO监听必须在监听器释放的时候,移除监听操作

 *  通知也得在释放的时候移除监听

 */

- (void)dealloc

{

    [self.itemremoveObserver:selfforKeyPath:@"title"];

    [self.itemremoveObserver:selfforKeyPath:@"image"];

    [self.itemremoveObserver:selfforKeyPath:@"selectedImage"];

    [self.itemremoveObserver:selfforKeyPath:@"badgeValue"];

}


/**

 *  监听item的属性值改变

 *

 *  @param keyPath 哪个属性改变了

 *  @param object  哪个对象的属性改变了

 */

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

    [selfsetTitle:self.item.titleforState:UIControlStateNormal];

    [selfsetImage:self.item.imageforState:UIControlStateNormal];

    [selfsetImage:self.item.selectedImageforState:UIControlStateSelected];

    

    // 设置提醒数字

    self.badgeButton.value =self.item.badgeValue;

    CGFloat badgeButtonX =self.frame.size.width -self.badgeButton.frame.size.width -5;

   CGFloat badgeButtonY = 2;

   self.badgeButton.frame =CGRectMake(badgeButtonX, badgeButtonY, 0, 0);

}

@end





//

//  ZZTabBar.h

//  ZZ_APP主流框架

//

//  Created by ZZ_Macpro on 15/9/25.

//  Copyright (c) 2015 ZZ_Macpro. All rights reserved.

//


#import <UIKit/UIKit.h>


@class ZZTabBar;


@protocol ZZTabBarDelegate <NSObject>


@optional

/**

 *  ZZTabBar上面的按钮被选中了

 *

 *  @param tabBar 被点击的ZZTabBar

 *  @param from   原来按钮的位置

 *  @param to     新被选中按钮的位置

 */

- (void)tabBar:(ZZTabBar *)tabBar didSelectedButtonFrom:(NSInteger)from to:(NSInteger)to;


/**

 *  ZZTabBar中间的加号按钮被点击了

 */

- (void)tabBarDidClickedPlusButton:(ZZTabBar *)tabBar;


@end


@interface ZZTabBar :UIView

/**

 *  添加按钮

 *

 *  @param item 模型数据

 */

- (void)addTabBarButtonWithItem:(UITabBarItem *)item;


/**

 *  代理 命名以及在理解上需要加强

 */

@property (nonatomic,weak) id<ZZTabBarDelegate> delegate;


@end



//

//  ZZTabBar.m

//  ZZ_APP主流框架

//

//  Created by ZZ_Macpro on 15/9/25.

//  Copyright (c) 2015 ZZ_Macpro. All rights reserved.

//


#import "ZZTabBar.h"

#import "ZZTabBarButton.h"


@interface ZZTabBar()

/**

 *  存放tabBar上面的按钮

 */

@property (nonatomic,strong) NSMutableArray *tabBarButtons;

/**

 *  tabBar上被选中的按钮

 */

@property (nonatomic,weak) ZZTabBarButton *selectedButton;

/**

 *  中间增加的加号按钮

 */

@property (nonatomic,weak) UIButton *plusButton;


@end


@implementation ZZTabBar


/**

 *  tabBarButtons懒加载 只初始化一次 不用管他何时创建

 */

- (NSMutableArray *)tabBarButtons

{

    if (_tabBarButtons ==nil) {

        _tabBarButtons = [NSMutableArrayarray];

    }

    return_tabBarButtons;

}


/**

 *  初始化 在初始化中添加加号按钮

 */

- (id)initWithFrame:(CGRect)frame

{

   self = [superinitWithFrame:frame];

   if (self) {

       if (!iOS7) {

            self.backgroundColor = [UIColorcolorWithPatternImage:[UIImageimageWithName:@"tabbar_background"]];

        }

        

        [selfaddPlusBtn];

    }

    return self;

}


/**

 *  添加+号按钮

 */

- (void)addPlusBtn

{

    // 1.创建按钮

    UIButton *plusButton = [UIButtonbuttonWithType:UIButtonTypeCustom];

    

    // 2.设置背景图片

    UIImage *bg = [UIImageimageWithName:@"tabbar_compose_button"];

    [plusButton setBackgroundImage:bgforState:UIControlStateNormal];

    [plusButton setBackgroundImage:[UIImageimageWithName:@"tabbar_compose_button_highlighted"]forState:UIControlStateHighlighted];

    

    // 3.设置顶部的加号按钮

    [plusButton setImage:[UIImageimageWithName:@"tabbar_compose_icon_add"]forState:UIControlStateNormal];

    [plusButton setImage:[UIImageimageWithName:@"tabbar_compose_icon_add_highlighted"]forState:UIControlStateHighlighted];

    

    // 4.监听按钮点击

    [plusButton addTarget:selfaction:@selector(plusClick)forControlEvents:UIControlEventTouchUpInside];


    [selfaddSubview:plusButton];

   /**

     *  对其进行引用后续进行操作

     */

   self.plusButton = plusButton;

}


/**

 *  监听加号点击

 */

- (void)plusClick

{

    // 通知代理

   if ([self.delegaterespondsToSelector:@selector(tabBarDidClickedPlusButton:)]) {

        [self.delegatetabBarDidClickedPlusButton:self];

    }

}


- (void)addTabBarButtonWithItem:(UITabBarItem *)item

{

    // 1.创建按钮

    ZZTabBarButton *button = [[ZZTabBarButtonalloc] init];

    

    // 2.传递模型数据

    button.item = item;

    

    // 3.添加按钮

    [button addTarget:selfaction:@selector(buttonClick:)forControlEvents:UIControlEventTouchDown];

    [selfaddSubview:button];

    [self.tabBarButtonsaddObject:button];

    

    // 4.默认选中

    if (self.tabBarButtons.count == 1) {

        [selfbuttonClick:button];

    }

}


- (void)buttonClick:(ZZTabBarButton *)button

{

    // 0.通知代理

   if ([self.delegaterespondsToSelector:@selector(tabBar:didSelectedButtonFrom:to:)]) {

        [self.delegatetabBar:selfdidSelectedButtonFrom:self.selectedButton.tagto:button.tag];

    }

    

    // 1.控制器选中按钮

    self.selectedButton.selected =NO;

    button.selected =YES;

   self.selectedButton = button;

}


/**

 *  布局子控件

 */

- (void)layoutSubviews

{

    [superlayoutSubviews];

    

    // 1.4个按钮固定的尺寸所以不需要写在循环里面节约性能

   CGFloat buttonW = self.frame.size.width /5;

   CGFloat buttonH = self.frame.size.height;

    

   for (int index =0; index < self.tabBarButtons.count; index++) {

       ZZTabBarButton *button = self.tabBarButtons[index];

        button.tag = index;

       CGFloat buttonX = index * buttonW;

        

       if (index >= 2) {

            buttonX += buttonW;

        }

        //循环一次 值变化一次所以这里才是如何用一个变量 表示出所有的控件

        button.frame =CGRectMake(buttonX, 0, buttonW, buttonH);

    }

    

    // 2.中间的+按钮

    self.plusButton.bounds = (CGRect){CGPointZero,self.plusButton.currentBackgroundImage.size};

    self.plusButton.center =CGPointMake(self.frame.size.width *0.5, self.frame.size.height *0.5);

}


@end



1 0