2018-10-16 14:56:36 u010960265 阅读数 896
  • 微信小程序开发实战第三季

    本季完成一个辩论赛计时器APP,涉及到动画使用、声音播放、action-sheet、tabBar、表单元素form、switch、slider、radio-group、button等,涉及到面向对象的编程思路

    18642 人正在学习 去看看 邹积超

先看下效果:

在这里插入图片描述

简单的说下大致结构和思路吧

tabbar的话也是遵循主流,自定义一个继承自系统UITabbar的HQTabbar,然后用KVC和系统的进行替换中间的凸起按钮和tabbar内部的子控件不是同一类型,是一个UIButton而已,根据tabbar内部子控件的类型去调整内部子控件的位置,从而腾出一个中间位置给凸起按钮给tabbar弄一个代理,添加一个点击中间凸起按钮的代理方法,让HQTabBarController成为它的代理,实现对应代理方法即可实现按钮点击。

如果对以上步骤有不清楚的地方可以看代码或者随时咨询我哦,这篇文字主要讲的核心就是中间按钮点击:

  1. 要想监听整个发布按钮的点击,包括凸起部分点击也有反应,那么我是通过在自定义的LBTabbar内部重写- (UIView
    *)hitTest:(CGPoint)point withEvent:(UIEvent *)even方法来实现的
  2. 我们都知道,凸起按钮是自定义的LBTabbar的子控件,默认情况下子控件尺寸如果超出父控件,那么超出的部分点击是没有反应的
  3. hitTest这个方法就是专门返回一个处理响应事件最合适view的,一般情况下我们不实现这个方法,默认就是让系统帮我们去判断处理事件响应最合适的view,一旦我们想要改变一下这种情况,我们就需要通过重写这个方法
  4. 我们的需求是只要我们点击的point在凸起按钮的任何位置(无论是否超出tabbar)都可以有响应,那么我们首先需要判断这个point是否在凸起按钮自身上
    [self convertPoint:point toView:self.plusBtn]
    这句代码就是将当前tabbar的触摸点转换坐标系,转换到凸起按钮的身上,它会生成一个新的点,然后我们通过 [self.plusBtn
    pointInside:newP
    withEvent:event]方法判断如果这个新的点是在发布按钮身上,那么处理点击事件最合适的view就是发布按钮,否则直接让系统帮我们处理点击事件就可以了
  5. 这里还有一步也是非常关键,因为我们重写了寻找最合适view的方法,那么我们还需要考虑什么情况下我们需要由我们自己选择最合适的view,什么情况下不需要,所以我们需要加一个判断if
    (self.isHidden == NO),
    这句代码代表了当前页面是有tabbar的,那么肯定是在导航控制器的根控制器页面,这个时候就需要由我们自己选择最合适的view,其他的push页面直接让系统选择
  6. 如果不做第五步判断,bug就是由导航控制器的根控制器页面push到其他页面后,点击该页面和tabbar凸起按钮同样的位置也会有反应
  7. 关键代码
//重写hitTest方法,去监听发布按钮的点击,目的是为了让凸出的部分点击也有反应
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    //这一个判断是关键,不判断的话push到其他页面,点击发布按钮的位置也是会有反应的,这样就不好了
    //self.isHidden == NO 说明当前页面是有tabbar的,那么肯定是在导航控制器的根控制器页面
    //在导航控制器根控制器页面,那么我们就需要判断手指点击的位置是否在发布按钮身上
    //是的话让发布按钮自己处理点击事件,不是的话让系统去处理点击事件就可以了
    if (self.isHidden == NO) {

        //将当前tabbar的触摸点转换坐标系,转换到发布按钮的身上,生成一个新的点
        CGPoint newP = [self convertPoint:point toView:self.plusBtn];

        //判断如果这个新的点是在发布按钮身上,那么处理点击事件最合适的view就是发布按钮
        if ( [self.plusBtn pointInside:newP withEvent:event]) {
            return self.plusBtn;
        }else{//如果点不在发布按钮身上,直接让系统处理就可以了
          return [super hitTest:point withEvent:event];
     }
   } 
    else {//tabbar隐藏了,那么说明已经push到其他的页面了,这个时候还是让系统去判断最合适的view处理就好了
        return [super hitTest:point withEvent:event];
    }
}

下面是排布tabbar里面的子控件的

- (void)layoutSubviews
{
    [super layoutSubviews];
    //系统自带的按钮类型是UITabBarButton,找出这些类型的按钮,然后重新排布位置,空出中间的位置
    Class class = NSClassFromString(@"UITabBarButton");

    self.plusBtn.size = CGSizeMake(self.plusBtn.currentBackgroundImage.size.width, self.plusBtn.currentBackgroundImage.size.height);

    self.plusBtn.centerX = self.centerX;
    //调整发布按钮的中线点Y值
    self.plusBtn.centerY = self.height * 0.5 - 2*LBMagin ;


        UILabel *label = [[UILabel alloc] init];
        label.text = @"发布";
        label.font = [UIFont systemFontOfSize:11];
        [label sizeToFit];
        label.textColor = [UIColor grayColor];
        [self addSubview:label];
        label.centerX = self.plusBtn.centerX;
        label.centerY = CGRectGetMaxY(self.plusBtn.frame) + LBMagin ;



    int btnIndex = 0;
    for (UIView *btn in self.subviews) {//遍历tabbar的子控件
        if ([btn isKindOfClass:class]) {//如果是系统的UITabBarButton,那么就调整子控件位置,空出中间位置
            //每一个按钮的宽度==tabbar的五分之一
            btn.width = self.width / 5;

            btn.x = btn.width * btnIndex;

            btnIndex++;
            //如果是索引是2(从0开始的),直接让索引++,目的就是让消息按钮的位置向右移动,空出来发布按钮的位置
            if (btnIndex == 2) {
                btnIndex++;
            }
            
        }
    }
}

OK,结束了,不足之处欢迎大家指正,共同学习
代码地址HQShopDemo

2018-01-17 15:20:28 doubleface999 阅读数 2075
  • 微信小程序开发实战第三季

    本季完成一个辩论赛计时器APP,涉及到动画使用、声音播放、action-sheet、tabBar、表单元素form、switch、slider、radio-group、button等,涉及到面向对象的编程思路

    18642 人正在学习 去看看 邹积超

效果:

PS:这里需要用到UIView一个分类的一些属性,参考http://blog.csdn.net/doubleface999/article/details/79085764,图标素材等自行上网找或者自己设计,这里就不提供了。最后在StoryBoard中选择TabBarController对应下面自定义的TabBarController即可

 

自定义TabBar

 MyTabBar.h

复制代码
 1 #import <UIKit/UIKit.h>
 2 
 3 @class MyTabBar;
 4 
 5 //MyTabBar的代理必须实现addButtonClick,以响应中间“+”按钮的点击事件
 6 @protocol MyTabBarDelegate <NSObject>
 7 
 8 -(void)addButtonClick:(MyTabBar *)tabBar;
 9 
10 @end
11 
12 @interface MyTabBar : UITabBar
13 
14 //指向MyTabBar的代理
15 @property (nonatomic,weak) id<MyTabBarDelegate> myTabBarDelegate;
16 
17 @end
复制代码

 

MyTabBar.m

复制代码
  1 #import "MyTabBar.h"
  2 #import "UIView+Category.h"
  3 
  4 #define AddButtonMargin 10
  5 
  6 @interface MyTabBar()
  7 
  8 //指向中间“+”按钮
  9 @property (nonatomic,weak) UIButton *addButton;
 10 //指向“添加”标签
 11 @property (nonatomic,weak) UILabel *addLabel;
 12 
 13 @end
 14 
 15 @implementation MyTabBar
 16 
 17 /*
 18 // Only override drawRect: if you perform custom drawing.
 19 // An empty implementation adversely affects performance during animation.
 20 - (void)drawRect:(CGRect)rect {
 21     // Drawing code
 22 }
 23 */
 24 
 25 -(instancetype)initWithFrame:(CGRect)frame
 26 {
 27     if(self = [super initWithFrame:frame])
 28     {
 29         //创建中间“+”按钮
 30         UIButton *addBtn = [[UIButton alloc] init];
 31         //设置默认背景图片
 32         [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon"] forState:UIControlStateNormal];
 33         //设置按下时背景图片
 34         [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon-Active"] forState:UIControlStateHighlighted];
 35         //添加响应事件
 36         [addBtn addTarget:self action:@selector(addBtnDidClick) forControlEvents:UIControlEventTouchUpInside];
 37         //将按钮添加到TabBar
 38         [self addSubview:addBtn];
 39         
 40         self.addButton = addBtn;
 41     }
 42     return self;
 43 }
 44 
 45 //响应中间“+”按钮点击事件
 46 -(void)addBtnDidClick
 47 {
 48     if([self.myTabBarDelegate respondsToSelector:@selector(addButtonClick:)])
 49     {
 50         [self.myTabBarDelegate addButtonClick:self];
 51     }
 52 }
 53 
 54 -(void)layoutSubviews
 55 {
 56     [super layoutSubviews];
 57     
 58     //去掉TabBar上部的横线
 59     for (UIView *view in self.subviews)
 60     {
 61         if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height <= 1)   //横线的高度为0.5
 62         {
 63             UIImageView *line = (UIImageView *)view;
 64             line.hidden = YES;
 65         }
 66     }
 67     
 68     //设置“+”按钮的位置
 69     self.addButton.centerX = self.centerX;
 70     self.addButton.centerY = self.height * 0.5 - 1.5 * AddButtonMargin;
 71     //设置“+”按钮的大小为图片的大小
 72     self.addButton.size = CGSizeMake(self.addButton.currentBackgroundImage.size.width, self.addButton.currentBackgroundImage.size.height);
 73     
 74     //创建并设置“+”按钮下方的文本为“添加”
 75     UILabel *addLbl = [[UILabel alloc] init];
 76     addLbl.text = @"添加";
 77     addLbl.font = [UIFont systemFontOfSize:10];
 78     addLbl.textColor = [UIColor grayColor];
 79     [addLbl sizeToFit];
 80 
 81     //设置“添加”label的位置
 82     addLbl.centerX = self.addButton.centerX;
 83     addLbl.centerY = CGRectGetMaxY(self.addButton.frame) + 0.5 * AddButtonMargin + 0.5;
 84     
 85     [self addSubview:addLbl];
 86     
 87     self.addLabel = addLbl;
 88     
 89     int btnIndex = 0;
 90     //系统自带的按钮类型是UITabBarButton,找出这些类型的按钮,然后重新排布位置,空出中间的位置
 91     Class class = NSClassFromString(@"UITabBarButton");
 92     for (UIView *btn in self.subviews) {//遍历TabBar的子控件
 93         if ([btn isKindOfClass:class]) {//如果是系统的UITabBarButton,那么就调整子控件位置,空出中间位置
 94             //每一个按钮的宽度等于TabBar的三分之一
 95             btn.width = self.width / 3;
 96             
 97             btn.x = btn.width * btnIndex;
 98             
 99             btnIndex++;
100             //如果索引是1(即“+”按钮),直接让索引加一
101             if (btnIndex == 1) {
102                 btnIndex++;
103             }
104             
105         }
106     }
107     //将“+”按钮放到视图层次最前面
108     [self bringSubviewToFront:self.addButton];
109 }
110 
111 //重写hitTest方法,去监听"+"按钮和“添加”标签的点击,目的是为了让凸出的部分点击也有反应
112 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
113     
114     //这一个判断是关键,不判断的话push到其他页面,点击“+”按钮的位置也是会有反应的,这样就不好了
115     //self.isHidden == NO 说明当前页面是有TabBar的,那么肯定是在根控制器页面
116     //在根控制器页面,那么我们就需要判断手指点击的位置是否在“+”按钮或“添加”标签上
117     //是的话让“+”按钮自己处理点击事件,不是的话让系统去处理点击事件就可以了
118     if (self.isHidden == NO)
119     {
120         
121         //将当前TabBar的触摸点转换坐标系,转换到“+”按钮的身上,生成一个新的点
122         CGPoint newA = [self convertPoint:point toView:self.addButton];
123         //将当前TabBar的触摸点转换坐标系,转换到“添加”标签的身上,生成一个新的点
124         CGPoint newL = [self convertPoint:point toView:self.addLabel];
125         
126         //判断如果这个新的点是在“+”按钮身上,那么处理点击事件最合适的view就是“+”按钮
127         if ( [self.addButton pointInside:newA withEvent:event])
128         {
129             return self.addButton;
130         }
131         //判断如果这个新的点是在“添加”标签身上,那么也让“+”按钮处理事件
132         else if([self.addLabel pointInside:newL withEvent:event])
133         {
134             return self.addButton;
135         }
136         else
137         {//如果点不在“+”按钮身上,直接让系统处理就可以了
138             
139             return [super hitTest:point withEvent:event];
140         }
141     }
142     else
143     {
144         //TabBar隐藏了,那么说明已经push到其他的页面了,这个时候还是让系统去判断最合适的view处理就好了
145         return [super hitTest:point withEvent:event];
146     }
147 }
148 
149 @end
复制代码

 

自定义TabBarController

MyTabBarController.h

1 #import <UIKit/UIKit.h>
2 
3 @interface MyTabBarController : UITabBarController
4 
5 @end

 

 

MyTabBarController.m

复制代码
 1 #import "MyTabBarController.h"
 2 #import "MyTabBar.h"
 3 
 4 
 5 @interface MyTabBarController () <MyTabBarDelegate> //实现自定义TabBar协议
 6 
 7 @end
 8 
 9 @implementation MyTabBarController
10 
11 - (void)viewDidLoad {
12     [super viewDidLoad];
13     // Do any additional setup after loading the view.
14     
15     //设置TabBar上第一个Item(明细)选中时的图片
16     UIImage *listActive = [UIImage imageNamed:@"ListIcon - Active(blue)"];
17     UITabBarItem *listItem = self.tabBar.items[0];
18     //始终按照原图片渲染
19     listItem.selectedImage = [listActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
20     
21     
22     //设置TabBar上第二个Item(报表)选中时的图片
23     UIImage *chartActive = [UIImage imageNamed:@"ChartIcon - Active(blue)"];
24     UITabBarItem *chartItem = self.tabBar.items[1];
25     //始终按照原图片渲染
26     chartItem.selectedImage = [chartActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
27     
28     //创建自定义TabBar
29     MyTabBar *myTabBar = [[MyTabBar alloc] init];
30     myTabBar.myTabBarDelegate = self;
31     
32     //利用KVC替换默认的TabBar
33     [self setValue:myTabBar forKey:@"tabBar"];
34 }
35 
36 
37 -(void)viewDidLayoutSubviews
38 {
39     [super viewDidLayoutSubviews];
40     //设置TabBar的TintColor
41     self.tabBar.tintColor = [UIColor colorWithRed:89/255.0 green:217/255.0 blue:247/255.0 alpha:1.0];
42 }
43 
44 - (void)didReceiveMemoryWarning {
45     [super didReceiveMemoryWarning];
46     // Dispose of any resources that can be recreated.
47 }
48 
49 
50 
51 #pragma mark - MyTabBarDelegate
52 -(void)addButtonClick:(MyTabBar *)tabBar
53 {
54     //测试中间“+”按钮是否可以点击并处理事件
55     UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"test" message:@"Test" preferredStyle:UIAlertControllerStyleAlert];
56     UIAlertAction *action = [UIAlertAction actionWithTitle:@"test" style:UIAlertActionStyleDefault handler:nil];
57     [controller addAction:action];
58     [self presentViewController:controller animated:YES completion:nil];
59     
60 }
61 
62 @end
复制代码

 原文链接:https://www.cnblogs.com/guitarandcode/p/5759208.html

2017-03-20 16:48:32 aa741649143 阅读数 5848
  • 微信小程序开发实战第三季

    本季完成一个辩论赛计时器APP,涉及到动画使用、声音播放、action-sheet、tabBar、表单元素form、switch、slider、radio-group、button等,涉及到面向对象的编程思路

    18642 人正在学习 去看看 邹积超

主要实现思路:
1.重写UITabBar:在init里面创建一个button来实现不规则的图标(添加新按钮)放在最中间 -(void)layoutSubviews调整系统原本的图标的坐标(为中间这个控件留出位置)
2.重写-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ 避免按钮超区不可点击

看具体的代码:
自定义SamTabBar视图

//
//  SamTabBar.h
//  MoJing
//
//  Created by linpeng on 2017/3/15.
//  Copyright © 2017年 linpeng. All rights reserved.
//

#import <UIKit/UIKit.h>
//tab页面个数
typedef NS_ENUM(NSInteger, SamItemUIType) {
    SamItemUIType_Three = 3,//底部3个选项
    SamItemUIType_Five = 5,//底部5个选项
};


@class SamTabBar;

@protocol SamTabBarDelegate <NSObject>

-(void)tabBar:(SamTabBar *)tabBar clickCenterButton:(UIButton *)sender;

@end

@interface SamTabBar : UITabBar

@property (nonatomic, weak) id<SamTabBarDelegate> tabDelegate;
@property (nonatomic, strong) NSString *centerBtnTitle;
@property (nonatomic, strong) NSString *centerBtnIcon;

+(instancetype)instanceCustomTabBarWithType:(SamItemUIType)type;

@end

m文件

//
//  SamTabBar.m
//  MoJing
//
//  Created by linpeng on 2017/3/15.
//  Copyright © 2017年 linpeng. All rights reserved.
//

#import "SamTabBar.h"

@interface SamTabBar()
@property(nonatomic, strong) UIButton *centerButton;
@property(nonatomic, strong) UILabel *centerTitle;
@property (nonatomic,assign) SamItemUIType type;

@end

@implementation SamTabBar

+(instancetype)instanceCustomTabBarWithType:(SamItemUIType)type{
    SamTabBar *tabBar = [[SamTabBar alloc] init];
    tabBar.type = type;
    return tabBar;
}

-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.translucent = NO;
        UIButton *plusBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        self.centerButton = plusBtn;
        [plusBtn addTarget:self action:@selector(plusBtnDidClick) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:plusBtn];

        UILabel *lblTitle = [[UILabel alloc] init];
        self.centerTitle = lblTitle;
        lblTitle.font = [UIFont systemFontOfSize:10];
        lblTitle.textColor = [UIColor blackColor];
        lblTitle.textAlignment = NSTextAlignmentCenter;
        [self addSubview:lblTitle];

    }
    return self;
}

-(void)plusBtnDidClick{
    if (self.tabDelegate && [self.tabDelegate respondsToSelector:@selector(tabBar:clickCenterButton:)]) {
        [self.tabDelegate tabBar:self clickCenterButton:self.centerButton];
    }
}

// 调整子视图的布局
-(void)layoutSubviews{
    [super layoutSubviews];
    CGFloat width = self.frame.size.width/self.type;
    Class class = NSClassFromString(@"UITabBarButton");
    for (UIView *view in self.subviews) {
        if ([view isEqual:self.centerTitle]) {//self.centerButton
            view.frame = CGRectMake(0, 0, width, 15);
            view.center = CGPointMake(self.frame.size.width/2, self.frame.size.height - view.frame.size.height + 8);
        }else if ([view isEqual:self.centerButton]) {//self.centerButton
            view.frame = CGRectMake(0, 0, width, self.frame.size.height);
            [view sizeToFit];
            view.center = CGPointMake(self.frame.size.width/2, 10);
        }else if ([view isKindOfClass:class]){//system button
            CGRect frame = view.frame;
            int indexFromOrign = view.frame.origin.x/width;//防止UIView *view in self.subviews 获取到的不是有序的
            if (indexFromOrign >= (self.type - 1) / 2) {
                indexFromOrign++;
            }
            CGFloat x = indexFromOrign * width;
            //如果是系统的UITabBarButton,那么就调整子控件位置,空出中间位置
            view.frame = CGRectMake(x, view.frame.origin.y, width, frame.size.height);

            //调整badge postion
            for (UIView *badgeView in view.subviews){
                NSString *className = NSStringFromClass([badgeView class]);
                // Looking for _UIBadgeView
                if ([className rangeOfString:@"BadgeView"].location != NSNotFound){
                    badgeView.layer.transform = CATransform3DIdentity;
                    badgeView.layer.transform = CATransform3DMakeTranslation(-17.0, 1.0, 1.0);
                    break;
                }
            }
        }
    }
}


-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    //这一个判断是关键,不判断的话push到其他页面,点击发布按钮的位置也是会有反应的,这样就不好了
    //self.isHidden == NO 说明当前页面是有tabbar的,那么肯定是在导航控制器的根控制器页面
    //在导航控制器根控制器页面,那么我们就需要判断手指点击的位置是否在发布按钮身上
    //是的话让发布按钮自己处理点击事件,不是的话让系统去处理点击事件就可以了
    if (self.isHidden == NO) {
        //将当前tabbar的触摸点转换坐标系,转换到发布按钮的身上,生成一个新的点
        CGPoint newP = [self convertPoint:point toView:self.centerButton];

        //判断如果这个新的点是在发布按钮身上,那么处理点击事件最合适的view就是发布按钮
        if ( [self.centerButton pointInside:newP withEvent:event]) {
            return self.centerButton;
        }else{//如果点不在发布按钮身上,直接让系统处理就可以了
            return [super hitTest:point withEvent:event];
        }
    }
    else {//tabbar隐藏了,那么说明已经push到其他的页面了,这个时候还是让系统去判断最合适的view处理就好了
        return [super hitTest:point withEvent:event];
    }
}

-(void)setCenterBtnIcon:(NSString *)centerBtnIcon{
    _centerBtnIcon = centerBtnIcon;
    [self.centerButton setBackgroundImage:[UIImage imageNamed:self.centerBtnIcon] forState:UIControlStateNormal];
    [self.centerButton setBackgroundImage:[UIImage imageNamed:self.centerBtnIcon] forState:UIControlStateHighlighted];
}

-(void)setCenterBtnTitle:(NSString *)centerBtnTitle{
    _centerBtnTitle = centerBtnTitle;
    self.centerTitle.text = centerBtnTitle;
}

@end

用法:
以上自定义的tabbar控件就弄好了 现在就可以在VC中使用了
创建一个WBTabBarController 继承UITabBarController 在appdelegate中

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = [[WBTabBarController alloc] init];

kvo的形式添加自定义的tabbar

 //kvo形式添加自定义的 UITabBar
    SamTabBar *tab = [SamTabBar instanceCustomTabBarWithType:SamItemUIType_Five];
    [self setValue:tab forKey:@"tabBar"];

具体的代码:

@interface WBTabBarController ()<SamTabBarDelegate>
@end

@implementation WBTabBarController

- (void)awakeFromNib {
    [super awakeFromNib];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
}

-(void)setupUI{
    [self setupVC];
    [[UITabBar appearance] setShadowImage:[UIImage new]];
    //kvo形式添加自定义的 UITabBar
    SamTabBar *tab = [SamTabBar instanceCustomTabBarWithType:SamItemUIType_Five];
    tab.centerBtnTitle = @"发布";
    tab.centerBtnIcon = @"摄影机图标_点击后";
    tab.tabDelegate = self;
    [self setValue:tab forKey:@"tabBar"];
}

- (void)setupVC{
    [self addChildVc:[[LoginViewController alloc] init] title:@"首页" image:@"TabMessage" selectedImage:@"TabMessage_HL"];
    [self addChildVc:[[LoginViewController alloc] init] title:@"发现" image:@"TabMessage" selectedImage:@"TabMessage_HL"];
    [self addChildVc:[[LoginViewController alloc] init] title:@"消息" image:@"TabMessage" selectedImage:@"TabMessage_HL"];
    [self addChildVc:[[LoginViewController alloc] init] title:@"个人中心" image:@"TabMessage" selectedImage:@"TabMessage_HL"];
}

- (void)addChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage{
    // 设置子控制器的文字(可以设置tabBar和navigationBar的文字)
    childVc.title = title;
    // 设置子控制器的tabBarItem图片
    childVc.tabBarItem.image = [UIImage imageNamed:image];
    // 禁用图片渲染
    childVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    // 设置文字的样式
    [childVc.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor blackColor]} forState:UIControlStateNormal];
    [childVc.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} forState:UIControlStateSelected];
    // 为子控制器包装导航控制器
    WBBaseNC *navigationVc = [[WBBaseNC alloc] initWithRootViewController:childVc];
    // 添加子控制器
    [self addChildViewController:navigationVc];
}

-(void)tabBar:(SamTabBar *)tabBar clickCenterButton:(UIButton *)sender{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"点击了中间按钮" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

    }];
    [alert addAction:action];
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

效果如图:
图片

gif效果如图:
gif效果

修改tabbar上那条很丑的分割线

-(void)setupUI{
    [self setupVC];
    //kvo形式添加自定义的 UITabBar
    SamTabBar *tab = [SamTabBar instanceCustomTabBarWithType:SamItemUIType_Five];
    tab.centerBtnTitle = nil;
    tab.centerBtnIcon = @"menu_diary_pr";
    tab.tabDelegate = self;
    [self setValue:tab forKey:@"tabBar"];

    //去除顶部很丑的border
    [[UITabBar appearance] setShadowImage:[UIImage new]];
    [[UITabBar appearance] setBackgroundImage:[[UIImage alloc]init]];

    //自定义分割线颜色
    UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(self.tabBar.bounds.origin.x-0.5, self.tabBar.bounds.origin.y, self.tabBar.bounds.size.width+1, self.tabBar.bounds.size.height+2)];
    bgView.layer.borderColor = COLOR_SEPERATOR.CGColor;
    bgView.layer.borderWidth = 0.5;
    [tab insertSubview:bgView atIndex:0];
    tab.opaque = YES;
}

效果:
这里写图片描述

2016-06-23 14:57:46 shan1991fei 阅读数 7373
  • 微信小程序开发实战第三季

    本季完成一个辩论赛计时器APP,涉及到动画使用、声音播放、action-sheet、tabBar、表单元素form、switch、slider、radio-group、button等,涉及到面向对象的编程思路

    18642 人正在学习 去看看 邹积超

先展示效果图:


这个tabBar纠结了我好久,最后通过查询资料各种百度谷歌终于找到一个比较符合我们需求的案例,下面展示出代码供各位参考

@interface BaseTabBarViewController ()<UITabBarControllerDelegate>
@property (nonatomic,strong)UIButton *button;
@end

@implementation BaseTabBarViewController
@synthesize button;
#pragma mark- setup
-(void)setup
{
    //  添加突出按钮
    [self addCenterButtonWithImage:[UIImage imageNamed:@"我的钱"] selectedImage:[UIImage imageNamed:@"我的钱"]];
    //  UITabBarControllerDelegate 指定为自己
    self.delegate=self;
    //  指定当前页——中间页
    //self.selectedIndex=0;
    //  设点button状态
    //button.selected=YES;
    //  设定其他item点击选中颜色
 
}
#pragma mark - addCenterButton
// Create a custom UIButton and add it to the center of our tab bar
-(void) addCenterButtonWithImage:(UIImage*)buttonImage selectedImage:(UIImage*)selectedImage
{
    button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button addTarget:self action:@selector(pressChange:) forControlEvents:UIControlEventTouchUpInside];
    button.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin;
    
    //  设定button大小为适应图片
    button.frame = CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
    [button setImage:buttonImage forState:UIControlStateNormal];
    [button setImage:selectedImage forState:UIControlStateSelected];
    
    //  这个比较恶心  去掉选中button时候的阴影
    button.adjustsImageWhenHighlighted=NO;
    /*
     *  核心代码:设置button的center 和 tabBar的 center 做对齐操作, 同时做出相对的上浮
     */
        CGPoint center = self.tabBar.center;
        center.y = center.y - buttonImage.size.height/4;
        button.center = center;
    [self.view addSubview:button];
}

-(void)pressChange:(id)sender
{
    self.selectedIndex=1;
    button.selected=YES;
}

#pragma mark- TabBar Delegate

//  换页和button的状态关联上

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
    if (self.selectedIndex==1) {
        button.selected=YES;
    }else
    {
        button.selected=NO;
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setTabBarVC];
    [self setup];
    [self addButtonNotifation];
    self.tabBar.barTintColor = [UIColor whiteColor];
}
//添加大圆按钮的通知
-(void)addButtonNotifation{
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(buttonHidden) name:@"buttonNotifationCenter" object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(buttonNotHidden) name:@"buttonNotHidden" object:nil];
}
-(void)buttonNotHidden{
    button.hidden=NO;
}
-(void)buttonHidden{
    button.hidden=YES;
}
// 初始化所有子控制器
- (void)setTabBarVC{
    [self setTabBarChildController:[[SelectionViewController alloc] init] title:@"每月送" image:@"每月送" selectImage:@"每月送选中"];

    [self setTabBarChildController:[[MyMoneyViewController alloc] init] title:@"我的钱" image:@"" selectImage:@""];
    
    [self setTabBarChildController:[[MainViewController alloc] init] title:@"个人中心" image:@"个人中心" selectImage:@"个人中心选中"];
}


// 添加tabbar的子viewcontroller
- (void)setTabBarChildController:(UIViewController*)controller title:(NSString*)title image:(NSString*)imageStr selectImage:(NSString*)selectImageStr{
    
    UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:controller];
    nav.tabBarItem.title = title;
    
    nav.tabBarItem.image = [[UIImage imageNamed:imageStr]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    nav.tabBarItem.selectedImage = [[UIImage imageNamed:selectImageStr]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    [nav.tabBarItem setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:10],NSForegroundColorAttributeName:RGBA(74, 74, 74, 1.0)} forState:UIControlStateNormal];
    [nav.tabBarItem setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:10],NSForegroundColorAttributeName:RGBA(255, 200, 0, 1.0)} forState:UIControlStateSelected];
    
    [self addChildViewController:nav];
}

tabBar的颜色各位可以用一张白色的图片做背景

关于那个隐藏大圆按钮的通知,我发现导航推进下一页的时候那个大圆按钮不会消失,我就只好用了一个通知控制隐藏和显示

如果各位有更好的方法也希望能够告知,共同进步

代码下载地址http://download.csdn.net/detail/shan1991fei/9557471

2016-08-10 23:03:00 weixin_30877181 阅读数 39
  • 微信小程序开发实战第三季

    本季完成一个辩论赛计时器APP,涉及到动画使用、声音播放、action-sheet、tabBar、表单元素form、switch、slider、radio-group、button等,涉及到面向对象的编程思路

    18642 人正在学习 去看看 邹积超

参考:http://www.jianshu.com/p/46f61bc7a938,https://github.com/Mringkang/KBCustomCenterTabbar

效果:

PS:这里需要用到UIView一个分类的一些属性,参考http://www.cnblogs.com/guitarandcode/p/5758995.html   ,图标素材等自行上网找或者自己设计,这里就不提供了。最后在StoryBoard中选择TabBarController对应下面自定义的TabBarController即可

 

自定义TabBar

 MyTabBar.h

 1 #import <UIKit/UIKit.h>
 2 
 3 @class MyTabBar;
 4 
 5 //MyTabBar的代理必须实现addButtonClick,以响应中间“+”按钮的点击事件
 6 @protocol MyTabBarDelegate <NSObject>
 7 
 8 -(void)addButtonClick:(MyTabBar *)tabBar;
 9 
10 @end
11 
12 @interface MyTabBar : UITabBar
13 
14 //指向MyTabBar的代理
15 @property (nonatomic,weak) id<MyTabBarDelegate> myTabBarDelegate;
16 
17 @end

 

MyTabBar.m

  1 #import "MyTabBar.h"
  2 #import "UIView+Category.h"
  3 
  4 #define AddButtonMargin 10
  5 
  6 @interface MyTabBar()
  7 
  8 //指向中间“+”按钮
  9 @property (nonatomic,weak) UIButton *addButton;
 10 //指向“添加”标签
 11 @property (nonatomic,weak) UILabel *addLabel;
 12 
 13 @end
 14 
 15 @implementation MyTabBar
 16 
 17 /*
 18 // Only override drawRect: if you perform custom drawing.
 19 // An empty implementation adversely affects performance during animation.
 20 - (void)drawRect:(CGRect)rect {
 21     // Drawing code
 22 }
 23 */
 24 
 25 -(instancetype)initWithFrame:(CGRect)frame
 26 {
 27     if(self = [super initWithFrame:frame])
 28     {
 29         //创建中间“+”按钮
 30         UIButton *addBtn = [[UIButton alloc] init];
 31         //设置默认背景图片
 32         [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon"] forState:UIControlStateNormal];
 33         //设置按下时背景图片
 34         [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon-Active"] forState:UIControlStateHighlighted];
 35         //添加响应事件
 36         [addBtn addTarget:self action:@selector(addBtnDidClick) forControlEvents:UIControlEventTouchUpInside];
 37         //将按钮添加到TabBar
 38         [self addSubview:addBtn];
 39         
 40         self.addButton = addBtn;
 41     }
 42     return self;
 43 }
 44 
 45 //响应中间“+”按钮点击事件
 46 -(void)addBtnDidClick
 47 {
 48     if([self.myTabBarDelegate respondsToSelector:@selector(addButtonClick:)])
 49     {
 50         [self.myTabBarDelegate addButtonClick:self];
 51     }
 52 }
 53 
 54 -(void)layoutSubviews
 55 {
 56     [super layoutSubviews];
 57     
 58     //去掉TabBar上部的横线
 59     for (UIView *view in self.subviews)
 60     {
 61         if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height <= 1)   //横线的高度为0.5
 62         {
 63             UIImageView *line = (UIImageView *)view;
 64             line.hidden = YES;
 65         }
 66     }
 67     
 68     //设置“+”按钮的位置
 69     self.addButton.centerX = self.centerX;
 70     self.addButton.centerY = self.height * 0.5 - 1.5 * AddButtonMargin;
 71     //设置“+”按钮的大小为图片的大小
 72     self.addButton.size = CGSizeMake(self.addButton.currentBackgroundImage.size.width, self.addButton.currentBackgroundImage.size.height);
 73     
 74     //创建并设置“+”按钮下方的文本为“添加”
 75     UILabel *addLbl = [[UILabel alloc] init];
 76     addLbl.text = @"添加";
 77     addLbl.font = [UIFont systemFontOfSize:10];
 78     addLbl.textColor = [UIColor grayColor];
 79     [addLbl sizeToFit];
 80 
 81     //设置“添加”label的位置
 82     addLbl.centerX = self.addButton.centerX;
 83     addLbl.centerY = CGRectGetMaxY(self.addButton.frame) + 0.5 * AddButtonMargin + 0.5;
 84     
 85     [self addSubview:addLbl];
 86     
 87     self.addLabel = addLbl;
 88     
 89     int btnIndex = 0;
 90     //系统自带的按钮类型是UITabBarButton,找出这些类型的按钮,然后重新排布位置,空出中间的位置
 91     Class class = NSClassFromString(@"UITabBarButton");
 92     for (UIView *btn in self.subviews) {//遍历TabBar的子控件
 93         if ([btn isKindOfClass:class]) {//如果是系统的UITabBarButton,那么就调整子控件位置,空出中间位置
 94             //每一个按钮的宽度等于TabBar的三分之一
 95             btn.width = self.width / 3;
 96             
 97             btn.x = btn.width * btnIndex;
 98             
 99             btnIndex++;
100             //如果索引是1(即“+”按钮),直接让索引加一
101             if (btnIndex == 1) {
102                 btnIndex++;
103             }
104             
105         }
106     }
107     //将“+”按钮放到视图层次最前面
108     [self bringSubviewToFront:self.addButton];
109 }
110 
111 //重写hitTest方法,去监听"+"按钮和“添加”标签的点击,目的是为了让凸出的部分点击也有反应
112 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
113     
114     //这一个判断是关键,不判断的话push到其他页面,点击“+”按钮的位置也是会有反应的,这样就不好了
115     //self.isHidden == NO 说明当前页面是有TabBar的,那么肯定是在根控制器页面
116     //在根控制器页面,那么我们就需要判断手指点击的位置是否在“+”按钮或“添加”标签上
117     //是的话让“+”按钮自己处理点击事件,不是的话让系统去处理点击事件就可以了
118     if (self.isHidden == NO)
119     {
120         
121         //将当前TabBar的触摸点转换坐标系,转换到“+”按钮的身上,生成一个新的点
122         CGPoint newA = [self convertPoint:point toView:self.addButton];
123         //将当前TabBar的触摸点转换坐标系,转换到“添加”标签的身上,生成一个新的点
124         CGPoint newL = [self convertPoint:point toView:self.addLabel];
125         
126         //判断如果这个新的点是在“+”按钮身上,那么处理点击事件最合适的view就是“+”按钮
127         if ( [self.addButton pointInside:newA withEvent:event])
128         {
129             return self.addButton;
130         }
131         //判断如果这个新的点是在“添加”标签身上,那么也让“+”按钮处理事件
132         else if([self.addLabel pointInside:newL withEvent:event])
133         {
134             return self.addButton;
135         }
136         else
137         {//如果点不在“+”按钮身上,直接让系统处理就可以了
138             
139             return [super hitTest:point withEvent:event];
140         }
141     }
142     else
143     {
144         //TabBar隐藏了,那么说明已经push到其他的页面了,这个时候还是让系统去判断最合适的view处理就好了
145         return [super hitTest:point withEvent:event];
146     }
147 }
148 
149 @end

 

自定义TabBarController

MyTabBarController.h

1 #import <UIKit/UIKit.h>
2 
3 @interface MyTabBarController : UITabBarController
4 
5 @end

 

 

MyTabBarController.m

 1 #import "MyTabBarController.h"
 2 #import "MyTabBar.h"
 3 
 4 
 5 @interface MyTabBarController () <MyTabBarDelegate> //实现自定义TabBar协议
 6 
 7 @end
 8 
 9 @implementation MyTabBarController
10 
11 - (void)viewDidLoad {
12     [super viewDidLoad];
13     // Do any additional setup after loading the view.
14     
15     //设置TabBar上第一个Item(明细)选中时的图片
16     UIImage *listActive = [UIImage imageNamed:@"ListIcon - Active(blue)"];
17     UITabBarItem *listItem = self.tabBar.items[0];
18     //始终按照原图片渲染
19     listItem.selectedImage = [listActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
20     
21     
22     //设置TabBar上第二个Item(报表)选中时的图片
23     UIImage *chartActive = [UIImage imageNamed:@"ChartIcon - Active(blue)"];
24     UITabBarItem *chartItem = self.tabBar.items[1];
25     //始终按照原图片渲染
26     chartItem.selectedImage = [chartActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
27     
28     //创建自定义TabBar
29     MyTabBar *myTabBar = [[MyTabBar alloc] init];
30     myTabBar.myTabBarDelegate = self;
31     
32     //利用KVC替换默认的TabBar
33     [self setValue:myTabBar forKey:@"tabBar"];
34 }
35 
36 
37 -(void)viewDidLayoutSubviews
38 {
39     [super viewDidLayoutSubviews];
40     //设置TabBar的TintColor
41     self.tabBar.tintColor = [UIColor colorWithRed:89/255.0 green:217/255.0 blue:247/255.0 alpha:1.0];
42 }
43 
44 - (void)didReceiveMemoryWarning {
45     [super didReceiveMemoryWarning];
46     // Dispose of any resources that can be recreated.
47 }
48 
49 
50 
51 #pragma mark - MyTabBarDelegate
52 -(void)addButtonClick:(MyTabBar *)tabBar
53 {
54     //测试中间“+”按钮是否可以点击并处理事件
55     UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"test" message:@"Test" preferredStyle:UIAlertControllerStyleAlert];
56     UIAlertAction *action = [UIAlertAction actionWithTitle:@"test" style:UIAlertActionStyleDefault handler:nil];
57     [controller addAction:action];
58     [self presentViewController:controller animated:YES completion:nil];
59     
60 }
61 
62 @end

 

转载于:https://www.cnblogs.com/guitarandcode/p/5759208.html

没有更多推荐了,返回首页