iOS并排按钮点击联动效果封装

#import <UIKit/UIKit.h>

typedef void(^SelectedBlock)(id viewPager, NSInteger index);

@interface YFViewPager : UIView<UIScrollViewDelegate>
{
    NSArray *_titleArray;           /**< 菜单标题 */
    NSArray *_views;                /**< 视图 */
    NSArray *_titleIconsArray;      /**< 菜单标题左侧的小图标 */
    NSArray *_selectedIconsArray;   /**< 菜单被选中时左侧的小图标 */
    NSArray *_tipsCountArray;       /**< 菜单右上角的小红点显示的数量 */
}

@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *pageControl;

/**
 *  设置viewPager是否允许滚动 默认支持
 */
@property (nonatomic, assign) BOOL   enabledScroll;

/**
 *  当前选择的菜单索引
 */
@property (nonatomic, assign) NSInteger selectIndex;

/**
 *  菜单按钮背景属性
 */
@property (nonatomic, strong) UIColor *tabBgColor;
@property (nonatomic, strong) UIColor *tabSelectedBgColor;

/**
 *  菜单按钮下方横线背景属性
 */
@property (nonatomic, strong) UIColor *tabArrowBgColor;
@property (nonatomic, strong) UIColor *tabSelectedArrowBgColor;

/**
 *  菜单按钮的标题颜色属性
 */
@property (nonatomic, strong) UIColor *tabTitleColor;
@property (nonatomic, strong) UIColor *tabSelectedTitleColor;

/**
 *  是否显示垂直分割线  默认显示
 */
@property (nonatomic, assign) BOOL showVLine;

/**
 *  是否显示底部横线  默认显示
 */
@property (nonatomic, assign) BOOL showBottomLine;

/**
 *  选中状态是否显示底部横线  默认显示
 */
@property (nonatomic, assign) BOOL showSelectedBottomLine;

/**
 *  是否显示垂直分割线  默认显示
 */
@property (nonatomic, assign) BOOL showAnimation;

/**
 *  初始化 YFViewPager的方法
 *
 *  @param frame  frame
 *  @param titles 标题数组
 *  @param views  视图数组 和标题数组一一对应
 *
 *  @return YFViewPager
 */
- (id)initWithFrame:(CGRect)frame
             titles:(NSArray<NSString *> *)titles
              views:(NSArray<__kindof UIView *> *)views;

/**
 *  设置选择的菜单按钮
 *
 *  @param index 按钮的索引值 从左到右一次是0,1,2,3...
 */
- (void)setSelectIndex:(NSInteger)index;

/**
 *  点击菜单按钮时 调用的block方法
 *
 *  @param block 返回YFViewPager本身和点击的按钮的索引值,从左到右一次是0,1,2,3...
 */
- (void)didSelectedBlock:(SelectedBlock)block;

#pragma mark - version 2.0

/**
 *  初始化 YFViewPager的方法
 *
 *  @param frame  frame
 *  @param titles 标题数组
 *  @param icons 标题右侧图标数组
 *  @param selectedIcons 标题右侧选中时的图标数组
 *  @param views  视图数组 和标题数组一一对应
 *
 *  @return YFViewPager
 */
- (id)initWithFrame:(CGRect)frame
             titles:(NSArray<NSString *> *)titles
              icons:(NSArray<UIImage *> *)icons
      selectedIcons:(NSArray<UIImage *> *)selectedIcons
              views:(NSArray<__kindof UIView *> *)views;

/**
 *  设置菜单标题左边的icon 图标
 *
 *  @param icons 图标image
 *  @param selectedIcons 菜单被选中时显示的图标image
 */
- (void)setTitleIconsArray:(NSArray<UIImage *> *)icons selectedIconsArray:(NSArray<UIImage *> *)selectedIcons;

/**
 *  设置菜单右上角小红点显示的文字,数组需与菜单一一对应,数字为0时 赋值 @0或@""
 *
 *  @param tips 小红点上的文字
 */
- (void)setTipsCountArray:(NSArray *)tips;

@end
#import "YFViewPager.h"

#import "Public.h"


#ifdef DEBUG
#define DLog(s, ...) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DLog(s, ...)
#endif

@implementation YFViewPager
{
    SelectedBlock _block;
    NSInteger _pageNum;
}

//初始化
- (id)initWithFrame:(CGRect)frame
             titles:(NSArray<NSString *> *)titles
              views:(NSArray<__kindof UIView *> *)views
{
    self = [super initWithFrame:frame];
    if (self) {
        _views = views;
        _titleArray = titles;
        self.backgroundColor = [UIColor grayColor];
        [self configSelf];
    }
    return self;
}

//设置默认属性
- (void)configSelf
{
    self.userInteractionEnabled = YES;
    _tabBgColor = RGB(235, 235, 235);
    _tabArrowBgColor = [UIColor orangeColor];
    _tabTitleColor = [UIColor grayColor];
    _tabSelectedBgColor =RGB(235, 235, 235);
    _tabSelectedTitleColor = [UIColor orangeColor];
    _tabSelectedArrowBgColor =[UIColor orangeColor];
    _showVLine = NO;
    _showAnimation = YES;
    _showBottomLine = NO;
    _showSelectedBottomLine = YES;
    _enabledScroll = YES;
}

//视图重绘
- (void)drawRect:(CGRect)rect
{
    // Drawing code
    _scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 2, rect.size.width, rect.size.height - 2)];
    _scrollView.userInteractionEnabled = YES;
    _scrollView.showsHorizontalScrollIndicator = NO;
    _scrollView.showsVerticalScrollIndicator = NO;
    _scrollView.pagingEnabled = YES;
    _scrollView.directionalLockEnabled = YES;
    _scrollView.bounces = NO;
    _scrollView.backgroundColor = [UIColor whiteColor];
    CGRect frame;
    frame.origin.y = 38;
    frame.size.height = _scrollView.frame.size.height - 40;
    frame.size.width = rect.size.width;
    
    _pageControl = [[UIView alloc]initWithFrame:CGRectMake(0, 0, rect.size.width, 40)];
    _pageNum = _views.count;
    _pageControl.backgroundColor = [UIColor whiteColor];
    
    //创建菜单按钮下划线
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,  _pageControl.frame.size.height - 1, _pageControl.frame.size.width, 1)];
    label.backgroundColor = [UIColor lightGrayColor];
    label.tag = 200;
    
    UILabel *selectedLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, _pageControl.frame.size.height -3, _pageControl.frame.size.width/_pageNum, 3)];
    selectedLabel.backgroundColor = _tabSelectedArrowBgColor;
    selectedLabel.tag = 300;
    
    if (!_showBottomLine){
        CGRect labelFrame = label.frame;
        labelFrame.size.height = 0;
        label.frame = labelFrame;
    }
    
    if (!_showSelectedBottomLine) {
        CGRect selectedFrame = selectedLabel.frame;
        selectedFrame.size.height = 0;
        selectedLabel.frame = selectedFrame;
    }
    
    for (NSInteger i = 0; i < _views.count; i++) {
        //创建主视图
        UIView * view = [_views objectAtIndex:i];
        frame.origin.x = rect.size.width * i;
        [view setFrame:frame];
        [_scrollView addSubview:view];
        
        CGRect _pageframe = _pageControl.frame;
        _pageframe.size.width = rect.size.width / _pageNum;
        _pageframe.origin.x = _pageframe.size.width * i;
        
        //创建菜单按钮
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setFrame:_pageframe];
        button.tag = 100 + i;
        [button setTitleColor:_tabTitleColor forState:UIControlStateNormal];
        [button setTitleColor:_tabSelectedTitleColor forState:UIControlStateSelected];
        [button setBackgroundColor:_tabBgColor];
        [button setTitle:_titleArray[i] forState:UIControlStateNormal];
        button.titleLabel.font = [UIFont systemFontOfSize:15];
        [button addTarget:self action:@selector(tabBtnClicked:) forControlEvents:UIControlEventTouchUpInside];

        //创建菜单右侧小图标
        if (_titleIconsArray.count) {
            [button setImage:_titleIconsArray[i] forState:UIControlStateNormal];
        }
        if (_selectedIconsArray.count) {
            [button setImage:_selectedIconsArray[i] forState:UIControlStateSelected];
        }
        DLog(@"titleLabel.frame:x:%lf width:%lf height:%lf",button.titleLabel.frame.origin.x,button.titleLabel.frame.size.width,button.titleLabel.frame.size.height);
        //创建菜单按钮右上角的小红点
        UILabel *circleLabel = [[UILabel alloc] initWithFrame:CGRectMake([self getLabelWidth:_titleArray[i] fontSize:15]/2+button.titleLabel.frame.origin.x, 2, 16, 16)];
        circleLabel.backgroundColor = [UIColor redColor];
        circleLabel.textColor = [UIColor whiteColor];
        circleLabel.font = [UIFont systemFontOfSize:12];
        circleLabel.textAlignment = NSTextAlignmentCenter;
        circleLabel.tag = 600 +i;
        circleLabel.layer.cornerRadius = 8;
        circleLabel.layer.masksToBounds = YES;
        circleLabel.clipsToBounds = YES;

        if (_tipsCountArray == nil || _tipsCountArray.count == 0) {
            circleLabel.hidden = YES;
        }else if ([_tipsCountArray[i] integerValue] == 0){
            circleLabel.hidden = YES;
        }else{
            circleLabel.hidden = NO;
            circleLabel.text = [_tipsCountArray[i] integerValue]>99?@"99+":[NSString stringWithFormat:@"%@",_tipsCountArray[i]];
            CGPoint center = circleLabel.center;
            
            CGRect cFrame = circleLabel.frame;
            cFrame.size.width = [self getLabelWidth:circleLabel.text fontSize:12]+6>16?[self getLabelWidth:circleLabel.text fontSize:12]+6:16;
            
            circleLabel.frame = cFrame;
            circleLabel.center = center;
        }
        
        
        if (_showVLine) {
            //创建中间分割线
            UILabel *vlabel = [[UILabel alloc] initWithFrame:CGRectMake(-1, 10, 1, button.frame.size.height - 20)];
            vlabel.backgroundColor = _tabArrowBgColor;
            [button addSubview:vlabel];
            
            if (!i) {
                vlabel.hidden = YES;
            }
        }
        
        if (!i) {
            button.selected = YES;
        }
        if (button.selected) {
            [UIView animateWithDuration:0.3 animations:^{
                CGRect sframe = selectedLabel.frame;
                sframe.origin.x = button.frame.origin.x;
                selectedLabel.frame = sframe;
                [button setBackgroundColor:_tabSelectedBgColor];
            }];
        }
        [button addSubview:circleLabel];
        [_pageControl addSubview:button];
    }
    
    [_pageControl addSubview:label];
    [_pageControl addSubview:selectedLabel];
    
    if (_pageNum == 1) {
        _pageControl.hidden = YES;
    }
    
    if (_enabledScroll) {
        [_scrollView setContentSize:CGSizeMake(rect.size.width * _views.count + 1, rect.size.height - 2)];
    }else{
        [_scrollView setContentSize:CGSizeZero];
    }
    _scrollView.delegate = self;
    [self addSubview:_scrollView];
    [self addSubview:_pageControl];
}

//按钮的点击事件
- (void)tabBtnClicked:(UIButton *)sender
{
    NSInteger index = sender.tag - 100;
    
    if (_showAnimation) {
        [UIView beginAnimations:@"navTab" context:nil];
        [UIView setAnimationDuration:0.3];
        [self setSelectIndex:index];
        _scrollView.contentOffset = CGPointMake(index * self.frame.size.width, 0);
        [UIView commitAnimations];
    }else{
        [self setSelectIndex:index];
        _scrollView.contentOffset = CGPointMake(index * self.frame.size.width, 0);
    }
}

//设置选择的按钮索引 触发的方法
- (void)setSelectIndex:(NSInteger)index
{
    if(_block){
        _block(self,index);
    }
    _selectIndex = index;
    for (NSInteger i = 0; i<_pageNum; i++) {
        UIButton *btn = (UIButton *)[self viewWithTag:i + 100];
        btn.backgroundColor = _tabBgColor;
        btn.selected = NO;
    }
    
    UIButton *button = (UIButton *)[_pageControl viewWithTag:index + 100];
    UILabel *selectedLabel = (UILabel *)[_pageControl viewWithTag:300];
    button.backgroundColor = _tabSelectedBgColor;
    button.selected = YES;
    
    if (_showAnimation) {
        [UIView animateWithDuration:0.3 animations:^{
            CGRect frame = selectedLabel.frame;
            frame.origin.x = button.frame.origin.x;
            selectedLabel.frame = frame;
        }];
    }else{
        CGRect frame = selectedLabel.frame;
        frame.origin.x = button.frame.origin.x;
        selectedLabel.frame = frame;
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    NSInteger index = scrollView.contentOffset.x/self.frame.size.width;
    [self setSelectIndex:index];
}

- (void)setTabSelectedBgColor:(UIColor *)tabSelectedBgColor
{
    _tabSelectedBgColor = tabSelectedBgColor;
    [self setNeedsDisplay];
}

- (void)didSelectedBlock:(SelectedBlock)block
{
    _block = block;
}

- (NSInteger)getLabelWidth:(NSString *)string fontSize:(CGFloat)size
{
    CGSize stringSize = [string sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:size]}];
    CGFloat width = stringSize.width;
    return width;
}

#pragma mark - version 2.0

- (id)initWithFrame:(CGRect)frame
             titles:(NSArray<NSString *> *)titles
              icons:(NSArray<UIImage *> *)icons
      selectedIcons:(NSArray<UIImage *> *)selectedIcons
              views:(NSArray<__kindof UIView *> *)views
{
    self = [super initWithFrame:frame];
    if (self) {
        _views = views;
        _titleArray = titles;
        _titleIconsArray = icons;
        _selectedIconsArray = selectedIcons;
        self.backgroundColor = [UIColor grayColor];
        [self configSelf];
    }
    return self;
}

- (void)setTitleIconsArray:(NSArray<UIImage *> *)icons
        selectedIconsArray:(NSArray<UIImage *> *)selectedIcons
{
    _titleIconsArray = icons;
    _selectedIconsArray = selectedIcons;

    [self setNeedsDisplay];
}

//设置菜单标题右上角小红点上显示的数字
- (void)setTipsCountArray:(NSArray *)tips
{
    _tipsCountArray = tips;
    [self setNeedsDisplay];
}
@end

 

posted @ 2016-10-04 11:12  羽若其  阅读(1618)  评论(0编辑  收藏  举报