iOS - 网易新闻音乐滑动导航条实现(代码简单,自定义扩展)

没错 今天还上班。。。。
github地址
代码前说明:
为了支持外部的多tableView之类的UI手动的滑动,即安卓的seg可以手动滑动,所以按钮的点击只执行一个代理方法,并不做UI上的修改,在外部的代理(1)调用相应方法或者(2)对scrollView进行偏转操作,从而触发scrollView的代理方法,在scrollView代理方法再调用设置方法,从而将设置代码的触发集中到一个方法里
实质上就是所有的设置都是直接或者间接通过scrollView完成

使用方法:

_segView = [[QZScrollSegmentView alloc] initWithFrame:CGRectMake(0, 20, SCREEN_WIDTH, 40) andItems:@[@"项目",@"投资人",@"投资机构",@"文章",@"融资事件",@"创投活动",@"项目",@"投资人",@"投资机构",@"文章",@"融资事件",@"创投活动"] andNormalFontColor:UIColorFromRGB(0x666666) andSelectedColor:UIColorFromRGB(0x4a92eb) andLineColor:UIColorFromRGB(0x4a92eb) andItemFont:[UIFont systemFontOfSize:15] andHalfIntervalBetweenItems:30];
    _segView.delegate = self;
    [self.view addSubview:_segView];


- (void)chooseSegWithIndex:(NSInteger)index
{
    [_segView setCurrentIndex:index];
}

.h

#import <UIKit/UIKit.h>
@protocol QZScrollSegmentViewDelegate <NSObject>
- (void)chooseSegWithIndex:(NSInteger)index;
@end

@interface QZScrollSegmentView : UIView
@property (nonatomic,weak) id<QZScrollSegmentViewDelegate> delegate;
/**
 desc:初始化方法
 @param frame frame
 @param items 标题数组
 @param normalColor 未选择时候文字颜色
 @param selectColor 选择时候文字颜色
 @param lineColor 滑动的线的颜色
 @param font 文字字体
 @param interval 文字和文字之前的间距(一半,内部计算时候乘以2)
 */
-(instancetype)initWithFrame:(CGRect)frame
                    andItems:(NSArray *)items
          andNormalFontColor:(UIColor *)normalColor
            andSelectedColor:(UIColor *)selectColor
                andLineColor:(UIColor *)lineColor
                 andItemFont:(UIFont *)font
 andHalfIntervalBetweenItems:(CGFloat)interval;
/**
 * 设置选中的按钮
 */
-(void)setCurrentIndex:(NSInteger)index;
/**
 * 添加毛玻璃
 */
-(void)addEffectView;
@end

.m

#import "QZScrollSegmentView.h"
#import "NSString+QZExtension.h"

#define ITEM_BTN_TAG  10086
#define LineInterval 10

@interface QZScrollSegmentView()
{
    UIColor *_selectColor;
    UIColor *_normalColor;
    UIColor *_moveLineColor;
    UIFont  *_itemFont;
    CGFloat  _interval;
    CGFloat  _totalWidth;

    UIButton *_yuanBtn;

}
@property (nonatomic,strong) UIScrollView *scrollView;
@property (nonatomic,strong) NSArray *itemsArray;
@property (nonatomic,assign) NSInteger selectedIndex; // 选中的按钮的index
@property (nonatomic,strong) NSMutableArray *btnWidthAry;
@property (nonatomic,strong) NSMutableArray *btnArray; // 所有创建的btn
@property (nonatomic,strong) UILabel *moveLine;
@end

@implementation QZScrollSegmentView

-(instancetype)initWithFrame:(CGRect)frame
                    andItems:(NSArray *)items
          andNormalFontColor:(UIColor *)normalColor
            andSelectedColor:(UIColor *)selectColor
                andLineColor:(UIColor *)lineColor
                 andItemFont:(UIFont *)font
 andHalfIntervalBetweenItems:(CGFloat)interval
{
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor clearColor];

        self.itemsArray = [NSArray arrayWithArray:items];
        _selectColor = selectColor ==nil ? [UIColor redColor] : selectColor;
        _normalColor = normalColor ==nil ? UIColorFromRGB(0x333333) : normalColor;
        _moveLineColor = lineColor ==nil ? UIColorFromRGB(0x4a92eb) : lineColor;
        _itemFont = font == nil ? [UIFont systemFontOfSize:15] : font;
        self.selectedIndex = 0;
        _interval = interval == 0 ? 35 : interval;

        // 计算按钮宽度
        for (NSInteger i = 0; i<items.count; i++) {
            NSString *title = items[i];
            CGFloat titleWidth = [title widthWithFont:_itemFont] + _interval;
            _totalWidth += titleWidth;
            [self.btnWidthAry addObject:@(titleWidth)];
        }

        [self makeSubviews];
    }
    return self;
}

- (void)makeSubviews
{
    self.scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
    self.scrollView.scrollsToTop = NO;
    self.scrollView.showsHorizontalScrollIndicator=NO;
    self.scrollView.contentSize=CGSizeMake(_totalWidth, _scrollView.bounds.size.height);
    [self addSubview:self.scrollView];

    // 底部边框线
    UILabel *bottomLine=[[UILabel alloc] initWithFrame:CGRectMake(0, self.frame.size.height-0.5, self.frame.size.width, 0.5)];
    bottomLine.backgroundColor=UIColorFromRGB(0xe6e6e6);
    [_scrollView addSubview:bottomLine];

    // 滑动的线
    NSString *firstItem = [self.itemsArray firstObject];
    CGFloat titleWidth = [firstItem widthWithFont:_itemFont];
    self.moveLine=[[UILabel alloc] initWithFrame:CGRectMake( 0 , self.frame.size.height-2, titleWidth + LineInterval, 2)];
    self.moveLine.x = ([self.btnWidthAry[0] floatValue] - self.moveLine.width)/2.0;
    self.moveLine.backgroundColor = _moveLineColor;
    [self.scrollView addSubview:self.moveLine];

    // 创建点击按钮
    for (int i=0; i<self.itemsArray.count; i++)
    {
        UIButton *btn=[[UIButton alloc] initWithFrame:CGRectMake(0, 1, [self.btnWidthAry[i] floatValue], self.frame.size.height-2)];
        btn.titleLabel.font = _itemFont;
        btn.tag=ITEM_BTN_TAG + i;
        [self.btnArray addObject:btn];

        // 给按钮x赋值,第一个按钮不用,0
        if (btn.tag != ITEM_BTN_TAG) {
            UIButton *frontBtn = self.btnArray[i - 1];
            btn.x = frontBtn.right;
        }


        if (i ==_selectedIndex)
        {
            [btn setAttributedTitle:[[NSAttributedString alloc] initWithString:self.itemsArray[i] attributes:@{NSForegroundColorAttributeName:_selectColor}]  forState:UIControlStateNormal];
            _moveLine.centerX = btn.centerX;
            _yuanBtn=btn;

        }else{
            [btn setAttributedTitle:[[NSAttributedString alloc] initWithString:self.itemsArray[i] attributes:@{NSForegroundColorAttributeName:_normalColor}]  forState:UIControlStateNormal];
        }

        [btn addTarget:self action:@selector(btnClickedWithIndex:) forControlEvents:UIControlEventTouchUpInside];

        [_scrollView addSubview:btn];

    }
}

-(void)choseIndex:(UIButton *)btn
{
    NSInteger index= btn.tag- ITEM_BTN_TAG;

    if (index==_selectedIndex)
    {
        return;
    }

    [btn setAttributedTitle:[[NSAttributedString alloc] initWithString:btn.titleLabel.text attributes:@{NSForegroundColorAttributeName:_selectColor}]  forState:UIControlStateNormal];

    [_yuanBtn setAttributedTitle:[[NSAttributedString alloc] initWithString:_yuanBtn.titleLabel.text attributes:@{NSForegroundColorAttributeName:_normalColor}]  forState:UIControlStateNormal];

    [UIView animateWithDuration:0.1 animations:^{
        _scrollView.userInteractionEnabled=NO;
        _yuanBtn=btn;
        self.moveLine.width = [btn.titleLabel.text widthWithFont:_itemFont] + LineInterval;
        self.moveLine.centerX = btn.centerX;

    } completion:^(BOOL finished){
        _scrollView.userInteractionEnabled=YES;
        _selectedIndex=index;
    }];


}

- (void)btnClickedWithIndex:(UIButton *)btn
{
    NSInteger index= btn.tag- ITEM_BTN_TAG;
    /*==================
     *  code by Yu
     *  time: 17/01/25
     *  warning: 如果这里是支持外部scrollView滑动切换tableView的话就不要执行上面的所有操作,只执行代理,然后外部代理会代码设置scrollView滑动,然后触发scrollView Delegate,进而执行上面的动UI代码
     *==================*/
    if ([self.delegate respondsToSelector:@selector(chooseSegWithIndex:)]) {
        [self.delegate chooseSegWithIndex: index];
    }
}
-(void)setCurrentIndex:(NSInteger)index
{
    UIButton *btn=(UIButton *)[self viewWithTag:ITEM_BTN_TAG + index];

    // 按钮中心超过屏幕75%偏移 到62.5%
    if (btn.centerX > SCREEN_WIDTH * 0.75) {
        CGFloat scrollWidth = btn.centerX - SCREEN_WIDTH * 0.625;
        if (scrollWidth > _scrollView.contentSize.width - SCREEN_WIDTH) {
            [UIView animateWithDuration:0.5 animations:^{
                _scrollView.contentOffset=CGPointMake(_scrollView.contentSize.width - SCREEN_WIDTH, 0);
            }];
        }else{

            [UIView animateWithDuration:0.5 animations:^{
                _scrollView.contentOffset=CGPointMake(scrollWidth, 0);
            }];

        }

    }else{
        [UIView animateWithDuration:0.5 animations:^{
            _scrollView.contentOffset=CGPointMake(0, 0);
        }];
    }

    [self choseIndex:btn];

}

-(void)addEffectView
{
    UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *effView = [[UIVisualEffectView alloc] initWithEffect:effect];
    effView.frame = self.frame;
    [self addSubview:effView];
    [self sendSubviewToBack:effView];
    self.backgroundColor = [UIColor clearColor];
}

- (NSMutableArray*)btnArray
{
    if (!_btnArray) {
        _btnArray=[[NSMutableArray alloc] init];
    }
    return _btnArray;
}

- (NSMutableArray*)btnWidthAry
{
    if (!_btnWidthAry) {
        _btnWidthAry=[[NSMutableArray alloc] init];
    }
    return _btnWidthAry;
}

@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值