仿新浪微博学习笔记03

来源:互联网 发布:宫家的东西 知乎 编辑:程序博客网 时间:2024/04/28 14:56

在完成自定义tabbar之后,就可以进行下一步了,先来看下上次的运行图:



tabbar做到现在,可能有点晕了,因为有2层tabor以及button,下面就先来分析一下:



这张效果图的时候,是因为有2层的button叠加在一起了,



从左边(最底下)到右边(最上面一层),分别是:view,UITabBar(系统自带的tabor),customTabBar(自定义的tabbar),customButton(自定义的button),button(系统自带的tabor上面的button)。

正是因为这样,才会出现上面的红色的重叠的图。

后来我们把系统自带的UITabBar上面的button移除掉,即移除了最上层的button层。所以才会有现在的效果图。



接下来就是对按钮需要进行改变,标题位置等需要改。先把红色背景给去掉了。



标题看不到了,是因为都是白色的,不过仔细看还是能看到一点的。


那就开始修改button了,最后是封装tabbarbutton。


修改button:


@interface QLDTabBar ()@property (nonatomic, weak) UIButton *selectedButton;@end@implementation QLDTabBar-(instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithName:@"tabbar_background"]];    }    return  self;}- (void) addTabBarButtonWithItem: (UITabBarItem *)item{    //1.创建按钮,将button加载到QLDTabBar上    UIButton *button = [[UIButton alloc] init];    [self addSubview:button];        //2.设置按钮的数据    [button setTitle:item.title forState:UIControlStateNormal];    [button setImage:item.image forState:UIControlStateNormal];    [button setImage:item.selectedImage forState:UIControlStateSelected];    [button setBackgroundImage:[UIImage imageWithName:@"tabbar_slider"] forState:UIControlStateSelected];        //3.监听按钮的点击    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown];}/** *  监听按钮点击事件(达到每次只能选中一个按钮) */- (void)buttonClick: (UIButton *)button{    // 取消当前选中的按钮    self.selectedButton.selected = NO;    // 选中现在点击的按钮    button.selected = YES;    self.selectedButton = button;}

在这里改变了tabbar的背景,以及按钮选中的图片等,具体效果如下:



从上面运行图可以看大,title和image的摆放位置有问题,应该是上下的,而不是左右的,所以需要对button里面的一些方法进行重写,下面创建一个继承自UIButton的QLDTabBarButton:



然后在里面进行重写


#define QLDTabBarButtonImageRatio 0.6#import "QLDTabBarButton.h"@implementation QLDTabBarButton/** *  重写imageRectForContentRect方法,改变图片的位置 */-(CGRect)imageRectForContentRect:(CGRect)contentRect{    //为了能够达到效果,这里是使图片沾满一定的位置,这里的x,y是相对于button来说的    //图片的宽度就是按钮宽度    CGFloat imageW = contentRect.size.width;    CGFloat imageH = contentRect.size.height * QLDTabBarButtonImageRatio;    return CGRectMake(0, 0, imageW, imageH);}/** *  重写titleRectForContentRect方法,改变标题的位置 */-(CGRect)titleRectForContentRect:(CGRect)contentRect{    //在button里面,x = 0,但是y就不是了    CGFloat titleY = contentRect.size.height * QLDTabBarButtonImageRatio;    CGFloat titleW = contentRect.size.width;    CGFloat titleH = contentRect.size.height - titleY;    return CGRectMake(0, titleY, titleW, titleH);}@end

再回到QLDTabBar.m中,将UIButton全部替换成QLDTabBarButton


这里就是让按钮的位置进行改变,变成上下,而不是左右,看一下效果图:



虽然有点丑,但是毕竟目的达到了,起码变成上下位了,那么下面就可以进行其他设置了,先来将button进行一下封装:

还是用item进行传值,button在设置图片、标题的时候都是通过item进行设置的,所以就可以用这个来进行封装,即button.item = item;

在QLDTabBarButton.h中进行申明:

@property (nonatomic, strong) UITabBarItem *item;

然后在.m文件中重写setItem方法

通过重写item方法,可以改变button里面的item的属性


-(void)setItem:(UITabBarItem *)item{    _item = item;        [self setTitle:item.title forState:UIControlStateNormal];    [self setImage:item.image forState:UIControlStateNormal];    [self setImage:item.selectedImage forState:UIControlStateSelected];    [self setBackgroundImage:[UIImage imageWithName:@"tabbar_slider"] forState:UIControlStateSelected];}

不过由于backgroundImage只需要设置一次,不需要每次创建button的时候都进行一次,所以把这句话放到initWithFrame里面就可以


-(instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        //设置按钮被选中时的背景图片        [self setBackgroundImage:[UIImage imageWithName:@"tabbar_slider"] forState:UIControlStateSelected];    }    return  self;}


另外这边进行了封装,那么在QLDTabBar.m里面的addTabBarButtonWithItem,只需要进行如下操作:


- (void) addTabBarButtonWithItem: (UITabBarItem *)item{    //1.创建按钮,将button加载到QLDTabBar上    QLDTabBarButton *button = [[QLDTabBarButton alloc] init];    [self addSubview:button];        //2.设置按钮的数据    button.item = item;        //3.监听按钮的点击    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown];}

运行一下,效果图:



和上次的一样,但是这里存在一个问题,就是在点击按钮的时候,如果长按,则会显示灰色的,如下:



这是因为button有一个高亮的效果,下面可以取消这个效果,在QLDTabBarButton.m中:

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

运行后,效果如下:



下面就开始设置图片居中、文字居中、字体大小:

-(instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // 设置图片居中        self.imageView.contentMode = UIViewContentModeCenter;        // 设置文字居中        self.titleLabel.textAlignment = NSTextAlignmentCenter;        // 调节字体        self.titleLabel.font = [UIFont systemFontOfSize:11];                //设置按钮被选中时的背景图片        [self setBackgroundImage:[UIImage imageWithName:@"tabbar_slider"] forState:UIControlStateSelected];    }    return  self;}

运行后,效果如下:



这样好看多了,但是第一次进去之后,没有选中的按钮,所以需要在一进去后进行第0个按钮选中:


- (void) addTabBarButtonWithItem: (UITabBarItem *)item{    //1.创建按钮,将button加载到QLDTabBar上    QLDTabBarButton *button = [[QLDTabBarButton alloc] init];    [self addSubview:button];        //2.设置按钮的数据    button.item = item;        //3.监听按钮的点击    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown];        //4.默认选中第0个按钮    if (self.subviews.count == 1) {        [self buttonClick:button];    }}

这里只需要进行一次判断就可以,判断subviews加载的第一个页面,那这个按钮就是选中的按钮。

运行下,效果如下:



感觉挺好看的了

封装完了之后,那么需要实现navigationBar和button的同步,这需要用到代理,因为代理能够实现监听,能够自己帮你完成,通过点击不同button来控制外面的view controller,进而控制navigationBar。实现代理需要在QLDTabBar.h中shen'm申明:


#import <UIKit/UIKit.h>@class QLDTabBar;/** *  设置代理,通过代理能够告知TabBarViewController,从而能够改变navigationbar的显示 */@protocol QLDTabBarDelegate <NSObject>@optional// 代理,获取按钮从哪个跳转到哪个-(void) tabBar: (QLDTabBar *)tabBar didSelectedButtonFrom: (int) from to: (int)to;@end@interface QLDTabBar : UIView@property (nonatomic, weak) id<QLDTabBarDelegate> delegate;/** *  用item进行传值,每调用一次就可以创建一个tabbar */- (void) addTabBarButtonWithItem: (UITabBarItem *)item;@end


然后在.m文件中通知代理,并为每个button绑定不同的tag:


/** *  监听按钮点击事件(达到每次只能选中一个按钮) */- (void)buttonClick: (QLDTabBarButton *)button{    //1. 通知代理    if ([self.delegate respondsToSelector:@selector(tabBar:didSelectedButtonFrom:to:)]) {        //从当前的按钮跳到现在的按钮        [self.delegate tabBar:self didSelectedButtonFrom:self.selectedButton.tag to:button.tag];    }        //2.设置按钮的状态    // 取消当前选中的按钮    self.selectedButton.selected = NO;    // 选中现在点击的按钮    button.selected = YES;    self.selectedButton = button;}- (void)layoutSubviews{    [super layoutSubviews];        CGFloat buttonW = self.frame.size.width / self.subviews.count;    CGFloat buttonH = self.frame.size.height;    CGFloat buttonY = 0;    for (int index = 0; index < self.subviews.count; index++) {        //1.取出按钮        QLDTabBarButton *button = self.subviews[index];                //2.设置按钮的frame        CGFloat buttonX = index * buttonW;        button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);                //3.绑定tag (是为了能够在代理的时候区分到底是哪个按钮)        button.tag = index;    }}

最后是在QLDTabBarViewController.m文件中实现代理:


@interface QLDTabBarViewController () <QLDTabBarDelegate>/////此处把其他代码省略/** *  监听tabbar按钮的改变 */- (void) tabBar:(QLDTabBar *)tabBar didSelectedButtonFrom:(int)from to:(int)to{    NSLog(@"------%d------%d",from,to);}


运行之后,可以看到结果:



从结果中看出,这个代理是实现了的,所以,可以从这里面获得当前的按钮的tag,然后将其告知self.view就可以跳转到相应的view里去了,实现代码:


- (void) tabBar:(QLDTabBar *)tabBar didSelectedButtonFrom:(int)from to:(int)to{//    NSLog(@"------%d------%d",from,to);    self.selectedIndex = to;}

运行结果如下:



这样就实现了,但是由于在ios7及以上,新浪微博界面的tabbar的样子不是这样的,这种是ios6的,所以对图片以及标题还需要适配一下。


QLDTabBar里:


-(instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        if (!iOS7) { //如果不是ios7的,那么需要这个tabbar背景            self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithName:@"tabbar_background"]];        }    }    return  self;}

QLDTabBarButton里:


//图标的比例#define QLDTabBarButtonImageRatio 0.6//按钮的默认文字颜色#define QLDTabBarButtonTitleColor (iOS7 ? [UIColor blackColor] : [UIColor whiteColor])//按钮的选中文字颜色#define QLDTabBarButtonTitleSelectedColor ( iOS7 ? QLDColor(234,103,7) : QLDColor(248,139,0))#import "QLDTabBarButton.h"@implementation QLDTabBarButton-(instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // 设置图片居中        self.imageView.contentMode = UIViewContentModeCenter;        // 设置文字居中        self.titleLabel.textAlignment = NSTextAlignmentCenter;        // 调节字体        self.titleLabel.font = [UIFont systemFontOfSize:11];        // 设置字体颜色        [self setTitleColor: QLDTabBarButtonTitleColor forState:UIControlStateNormal];        [self setTitleColor:QLDTabBarButtonTitleSelectedColor forState:UIControlStateSelected];                if (!iOS7) { //如果不是ios7,那么需要这个button背景            //设置按钮被选中时的背景图片            [self setBackgroundImage:[UIImage imageWithName:@"tabbar_slider"] forState:UIControlStateSelected];        }    }    return  self;}

PrefixHeader.pch中是这样的:


#import <Availability.h>#ifndef __IPHONE_3_0#warning "This project uses features only available in iOS SDK 3.0 and later."#endif#ifdef __OBJC__#import <UIKit/UIKit.h>#import <Foundation/Foundation.h>#import "UIImage+QLD.h"// 1.判断是否为iOS7#define iOS7 ([[UIDevice currentDevice].systemVersion doubleValue] >= 7.0)// 2.获得RGB颜色#define QLDColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]#endif

完成之后,运行一下:



这样就行了。












0 0
原创粉丝点击