自定义滚动标签

#import <UIKit/UIKit.h>

@class SGTopTitleView;


@protocol SGTopTitleViewDelegate <NSObject>

// delegate 方法

- (void)SGTopTitleView:(SGTopTitleView *)topTitleView didSelectTitleAtIndex:(NSInteger)index;


@end


@interface SGTopTitleView : UIScrollView

/** 静止标题数组 */

@property (nonatomic, strong) NSArray *staticTitleArr;

/** 滚动标题数组 */

@property (nonatomic, strong) NSArray *scrollTitleArr;

/** 存入所有Label */

@property (nonatomic, strong) NSMutableArray *allTitleLabel;


#pragma mark - - - 以下属性一定要设置在 -> 标题数组 <- 之后, 否则无效果

/** 文字以及指示器颜色设置(默认为红色)*/

@property (nonatomic, strong) UIColor *titleAndIndicatorColor;

/** 是否隐藏指示器(默认为NO) 指示器的宽度是根据标题内容的宽度变化而变化的, 所以设置这个属性一定要在 -> 标题数组属性之后 */

@property (nonatomic, assign) BOOL isHiddenIndicator;

/** 背景指示器样式(默认指示器在标题文字下方, 设置此属性指示器显示在文字后方) */

@property (nonatomic, assign) BOOL showsTitleBackgroundIndicatorStyle;


@property (nonatomic, weak) id<SGTopTitleViewDelegate> delegate_SG;


/** 类方法 */

+ (instancetype)topTitleViewWithFrame:(CGRect)frame;



#pragma mark - - - 给外界ScrollView提供的方法以及自身方法实现

/** 静止标题选中颜色改变以及指示器位置变化 */

- (void)staticTitleLabelSelecteded:(UILabel *)label;

/** 滚动标题选中颜色改变以及指示器位置变化 */

- (void)scrollTitleLabelSelecteded:(UILabel *)label;

/** 滚动标题选中居中 */

- (void)scrollTitleLabelSelectededCenter:(UILabel




.#


#import "SGTopTitleView.h"

#import "UIView+SGExtension.h"


#define labelFontOfSize [UIFont systemFontOfSize:17]

#define SG_screenWidth [UIScreen mainScreen].bounds.size.width

#define selectedTitleAndIndicatorViewColor [UIColor redColor]


@interface SGTopTitleView ()

/** 静止标题Label */

@property (nonatomic, strong) UILabel *staticTitleLabel;

/** 滚动标题Label */

@property (nonatomic, strong) UILabel *scrollTitleLabel;

/** 选中标题时的Label */

@property (nonatomic, strong) UILabel *selectedTitleLabel;

/** 指示器 */

@property (nonatomic, strong) UIView *indicatorView;

@end


@implementation SGTopTitleView


/** label之间的间距(滚动时TitleLabel之间的间距) */

static CGFloat const labelMargin = 15;

/** 指示器的高度 */

static CGFloat const indicatorHeight = 2;


- (NSMutableArray *)allTitleLabel {

    if (_allTitleLabel == nil) {

        _allTitleLabel = [NSMutableArray array];

    }

    return _allTitleLabel;

}


- (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {

        self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.9];

        self.showsHorizontalScrollIndicator = NO;

        self.bounces = NO;

    }

    return self;

}


+ (instancetype)topTitleViewWithFrame:(CGRect)frame {

    return [[self alloc] initWithFrame:frame];

}



/**

 *  计算文字尺寸

 *

 *  @param text    需要计算尺寸的文字

 *  @param font    文字的字体

 *  @param maxSize 文字的最大尺寸

 */

- (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize {

    NSDictionary *attrs = @{NSFontAttributeName : font};

    return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;

}



#pragma mark - - - 重写静止标题数组的setter方法

- (void)setStaticTitleArr:(NSArray *)staticTitleArr {

    _staticTitleArr = staticTitleArr;

    

    // 计算scrollView的宽度

    CGFloat scrollViewWidth = self.frame.size.width;

    CGFloat labelX = 0;

    CGFloat labelY = 0;

    CGFloat labelW = scrollViewWidth / self.staticTitleArr.count;

    CGFloat labelH = self.frame.size.height - indicatorHeight * 0.5;

    

    for (NSInteger j = 0; j < self.staticTitleArr.count; j++) {

        // 创建静止时的标题Label

        self.staticTitleLabel = [[UILabel alloc] init];

        _staticTitleLabel.userInteractionEnabled = YES;

        _staticTitleLabel.text = self.staticTitleArr[j];

        _staticTitleLabel.textAlignment = NSTextAlignmentCenter;

        _staticTitleLabel.tag = j;

        

        // 设置高亮文字颜色

        _staticTitleLabel.highlightedTextColor = selectedTitleAndIndicatorViewColor;

        

        // 计算staticTitleLabelx

        labelX = j * labelW;

        

        _staticTitleLabel.frame = CGRectMake(labelX, labelY, labelW, labelH);

        

        // 添加到titleLabels数组

        [self.allTitleLabel addObject:_staticTitleLabel];

        

        // 添加点按手势

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(staticTitleClick:)];

        [_staticTitleLabel addGestureRecognizer:tap];

        

        // 默认选中第0label

        if (j == 0) {

            [self staticTitleClick:tap];

        }

        

        [self addSubview:_staticTitleLabel];

    }

    

    // 取出第一个子控件

    UILabel *firstLabel = self.subviews.firstObject;

    

    // 添加指示器

    self.indicatorView = [[UIView alloc] init];

    _indicatorView.backgroundColor = selectedTitleAndIndicatorViewColor;

    _indicatorView.SG_height = indicatorHeight;

    _indicatorView.SG_y = self.frame.size.height - indicatorHeight;

    [self addSubview:_indicatorView];

    

    

    // 指示器默认在第一个选中位置

    // 计算TitleLabel内容的Size

    CGSize labelSize = [self sizeWithText:firstLabel.text font:labelFontOfSize maxSize:CGSizeMake(MAXFLOAT, labelH)];

    _indicatorView.SG_width = labelSize.width;

    _indicatorView.SG_centerX = firstLabel.SG_centerX;

}


/** staticTitleClick的点击事件 */

- (void)staticTitleClick:(UITapGestureRecognizer *)tap {

    // 0.获取选中的label

    UILabel *selLabel = (UILabel *)tap.view;

    

    // 1.标题颜色变成红色,设置高亮状态下的颜色, 以及指示器位置

    [self staticTitleLabelSelecteded:selLabel];

    

    // 2.代理方法实现

    NSInteger index = selLabel.tag;

    if ([self.delegate_SG respondsToSelector:@selector(SGTopTitleView:didSelectTitleAtIndex:)]) {

        [self.delegate_SG SGTopTitleView:self didSelectTitleAtIndex:index];

    }

}


/** 静止标题选中颜色改变以及指示器位置变化 */

- (void)staticTitleLabelSelecteded:(UILabel *)label {

    // 取消高亮

    _selectedTitleLabel.highlighted = NO;

    

    // 颜色恢复

    _selectedTitleLabel.textColor = [UIColor blackColor];

    

    // 高亮

    label.highlighted = YES;

    

    _selectedTitleLabel = label;

    

    // 改变指示器位置

    [UIView animateWithDuration:0.20 animations:^{

        // 计算内容的Size

        CGSize labelSize = [self sizeWithText:_selectedTitleLabel.text font:labelFontOfSize maxSize:CGSizeMake(MAXFLOAT, self.frame.size.height - indicatorHeight)];

        self.indicatorView.SG_width = labelSize.width;

        self.indicatorView.SG_centerX = label.SG_centerX;

    }];

}



#pragma mark - - - 重写滚动标题数组的setter方法

- (void)setScrollTitleArr:(NSArray *)scrollTitleArr {

    _scrollTitleArr = scrollTitleArr;

    

    CGFloat labelX = 0;

    CGFloat labelY = 0;

    CGFloat labelH = self.frame.size.height - indicatorHeight * 0.5;

    

    for (NSUInteger i = 0; i < self.scrollTitleArr.count; i++) {

        /** 创建滚动时的标题Label */

        self.scrollTitleLabel = [[UILabel alloc] init];

        _scrollTitleLabel.userInteractionEnabled = YES;

        _scrollTitleLabel.text = self.scrollTitleArr[i];

        _scrollTitleLabel.textAlignment = NSTextAlignmentCenter;

        _scrollTitleLabel.tag = i;

        

        // 设置高亮文字颜色

        _scrollTitleLabel.highlightedTextColor = selectedTitleAndIndicatorViewColor;

        

        // 计算内容的Size

        CGSize labelSize = [self sizeWithText:_scrollTitleLabel.text font:labelFontOfSize maxSize:CGSizeMake(MAXFLOAT, labelH)];

        // 计算内容的宽度

        CGFloat labelW = labelSize.width + 2 * labelMargin;

        

        _scrollTitleLabel.frame = CGRectMake(labelX, labelY, labelW, labelH);

        

        // 计算每个labelX

        labelX = labelX + labelW;

        

        // 添加到titleLabels数组

        [self.allTitleLabel addObject:_scrollTitleLabel];

        

        // 添加点按手势

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollTitleClick:)];

        [_scrollTitleLabel addGestureRecognizer:tap];

        

        // 默认选中第0label

        if (i == 0) {

            [self scrollTitleClick:tap];

        }

        

        [self addSubview:_scrollTitleLabel];

    }

    

    // 计算scrollView的宽度

    CGFloat scrollViewWidth = CGRectGetMaxX(self.subviews.lastObject.frame);

    self.contentSize = CGSizeMake(scrollViewWidth, self.frame.size.height);

    

    // 取出第一个子控件

    UILabel *firstLabel = self.subviews.firstObject;

    

    // 添加指示器

    self.indicatorView = [[UIView alloc] init];

    _indicatorView.backgroundColor = selectedTitleAndIndicatorViewColor;

    _indicatorView.SG_height = indicatorHeight;

    _indicatorView.SG_y = self.frame.size.height - indicatorHeight;

    [self addSubview:_indicatorView];

    

    

    // 指示器默认在第一个选中位置

    // 计算TitleLabel内容的Size

    CGSize labelSize = [self sizeWithText:firstLabel.text font:labelFontOfSize maxSize:CGSizeMake(MAXFLOAT, labelH)];

    _indicatorView.SG_width = labelSize.width;

    _indicatorView.SG_centerX = firstLabel.SG_centerX;

}


/** scrollTitleClick的点击事件 */

- (void)scrollTitleClick:(UITapGestureRecognizer *)tap {

    // 0.获取选中的label

    UILabel *selLabel = (UILabel *)tap.view;

    

    // 1.标题颜色变成红色,设置高亮状态下的颜色, 以及指示器位置

    [self scrollTitleLabelSelecteded:selLabel];

    

    // 2.让选中的标题居中 (contentSize 大于self的宽度才会生效)

    [self scrollTitleLabelSelectededCenter:selLabel];

    

    // 3.代理方法实现

    NSInteger index = selLabel.tag;

    if ([self.delegate_SG respondsToSelector:@selector(SGTopTitleView:didSelectTitleAtIndex:)]) {

        [self.delegate_SG SGTopTitleView:self didSelectTitleAtIndex:index];

    }

}


/** 滚动标题选中颜色改变以及指示器位置变化 */

- (void)scrollTitleLabelSelecteded:(UILabel *)label {

    

    // 取消高亮

    _selectedTitleLabel.highlighted = NO;

    

    // 颜色恢复

    _selectedTitleLabel.textColor = [UIColor blackColor];

    

    // 高亮

    label.highlighted = YES;

    

    _selectedTitleLabel = label;

    

    // 改变指示器位置

    if (_showsTitleBackgroundIndicatorStyle == YES) {

        [UIView animateWithDuration:0.20 animations:^{

            self.indicatorView.SG_width = label.SG_width - labelMargin;

            self.indicatorView.SG_centerX = label.SG_centerX;

        }];

    } else {

        [UIView animateWithDuration:0.20 animations:^{

            self.indicatorView.SG_width = label.SG_width - 2 * labelMargin;

            self.indicatorView.SG_centerX = label.SG_centerX;

        }];

    }

}


/** 滚动标题选中居中 */

- (void)scrollTitleLabelSelectededCenter:(UILabel *)centerLabel {

    // 计算偏移量

    CGFloat offsetX = centerLabel.center.x - SG_screenWidth * 0.5;

    

    if (offsetX < 0) offsetX = 0;

    

    // 获取最大滚动范围

    CGFloat maxOffsetX = self.contentSize.width - SG_screenWidth;

    

    if (offsetX > maxOffsetX) offsetX = maxOffsetX;

    

    // 滚动标题滚动条

    [self setContentOffset:CGPointMake(offsetX, 0) animated:YES];

}



#pragma mark - - - setter

- (void)setIsHiddenIndicator:(BOOL)isHiddenIndicator {

    if (isHiddenIndicator == YES) {

        [self.indicatorView removeFromSuperview];

    }

}


- (void)setTitleAndIndicatorColor:(UIColor *)titleAndIndicatorColor {

    _titleAndIndicatorColor = titleAndIndicatorColor;

    

    for (UIView *subViews in self.allTitleLabel) {

        UILabel *label = (UILabel *)subViews;

        label.highlightedTextColor = titleAndIndicatorColor;

    }

    _indicatorView.backgroundColor = titleAndIndicatorColor;

}


- (void)setShowsTitleBackgroundIndicatorStyle:(BOOL)showsTitleBackgroundIndicatorStyle {

    _showsTitleBackgroundIndicatorStyle = showsTitleBackgroundIndicatorStyle;

    

    if (showsTitleBackgroundIndicatorStyle == YES) {

        

        [self.indicatorView removeFromSuperview];

        

        // 取出第一个子控件

        UILabel *firstLabel = self.subviews.firstObject;

        

        // 添加指示器

        self.indicatorView = [[UIView alloc] init];

        _indicatorView.backgroundColor = selectedTitleAndIndicatorViewColor;

        _indicatorView.SG_height = indicatorHeight;

        _indicatorView.SG_y = self.frame.size.height - indicatorHeight;

        [self addSubview:_indicatorView];

        

        // 指示器默认在第一个选中位置

        // 计算TitleLabel内容的Size

        CGSize labelSize = [self sizeWithText:firstLabel.text font:labelFontOfSize maxSize:CGSizeMake(MAXFLOAT, self.frame.size.height)];

        _indicatorView.SG_width = labelSize.width + labelMargin;

        _indicatorView.SG_centerX = firstLabel.SG_centerX;

        

        CGFloat indicatorViewHeight = 25;

        self.indicatorView.SG_height = indicatorViewHeight;

        self.indicatorView.SG_y = (self.frame.size.height - indicatorViewHeight) * 0.5;

    }

    

    self.indicatorView.alpha = 0.3;

    self.indicatorView.layer.cornerRadius = 5;

    self.indicatorView.layer.masksToBounds = YES;

}


*)



*/

centerLabel;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值