实现原理很简单,就是利用了scrollview进行自定义,对外部传入的scrollview滑动事件进行监听,源码如下:
(1)h文件代码
//
// ScrollViewIndicator.h
// PagerIndicator
//
// Created by zp on 17/5/11.
// Copyright 2017年 zp. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ScrollViewIndicator : UIScrollView<UIScrollViewDelegate>
@property(weak, nonatomic) UIScrollView *scroll;
@property(strong, nonatomic) NSArray *titles;
@property(strong, nonatomic) UIView *line;
@property(assign, nonatomic) int lineWidth;
@property(strong, nonatomic) UIButton *currentBtn;
@property(assign, nonatomic) BOOL didEndDecelerating;
+(instancetype)initWithTitles:(NSArray *)titles pages:(UIScrollView *)scrollView;
@end
//
// ScrollViewIndicator.m
// PagerIndicator
//
// Created by zp on 17/5/11.
// Copyright 2017年 zp. All rights reserved.
//
#import "ScrollViewIndicator.h"
@implementation ScrollViewIndicator
-(id)initWithTitles:(NSArray *)titles pages:(UIScrollView *)scrollView{
int screenWidth = [UIScreen mainScreen].bounds.size.width;
int width = screenWidth/4;
CGRect frame = CGRectMake(0, 0, screenWidth, 42);
self = [super initWithFrame:frame];
if(self){
self.contentSize = CGSizeMake(width*[titles count], 42);
self.pagingEnabled = NO;
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
self.backgroundColor = [UIColor lightGrayColor];
self.titles = titles;
self.lineWidth = width;
// scrollView.delegate = self;
self.scroll = scrollView;
self.scroll.delegate = self;
[self initTitles];
}
return self;
}
+(instancetype)initWithTitles:(NSArray *)titles pages:(UIScrollView *)scrollView{
ScrollViewIndicator *indicator = [[ScrollViewIndicator alloc]initWithTitles:titles pages:scrollView];
return indicator;
}
-(void)initTitles{
int width = [UIScreen mainScreen].bounds.size.width/4;
for(int i=0; i<_titles.count; i++){
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(i*width, 0, width, 39);
[button setTitle:[_titles objectAtIndex:i] forState:UIControlStateNormal];
[button setTintColor:[UIColor lightGrayColor]];
button.tag = i+100;
[button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
}
_line = [[UIView alloc]initWithFrame:CGRectMake(0, 39, width, 3)];
[_line setBackgroundColor:[UIColor whiteColor]];
[self addSubview:_line];
[self setIndex:0];
}
-(void)click:(UIButton *)sender{
[self setIndex:sender.tag-100];
}
-(void)setIndex:(NSInteger)index{
[self changeScrollOfSet:index];
[_scroll setContentOffset:CGPointMake(index*[UIScreen mainScreen].bounds.size.width, 0) animated:YES];
}
- (NSInteger)changeProgressToInteger:(float)x
{
float max = _titles.count;
float min = 0;
NSInteger index = 0;
if(x< min+0.5){
index = min;
}else if(x >= max-0.5){
index = max;
}else{
index = (x+0.5)/1;
}
return index;
}
//移动ScrollView
-(void)changeScrollOfSet:(NSInteger)index
{
[_currentBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
UIButton *button = (UIButton *)[self viewWithTag:index+100];
_currentBtn = button;
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
float halfWidth = CGRectGetWidth(self.frame)/2.0;
float scrollWidth = self.contentSize.width;
float leftSpace = _lineWidth*index - halfWidth;
if(index*_lineWidth<halfWidth-_lineWidth/2){
[self setContentOffset:CGPointMake(0, 0) animated:YES];
}
else if(_lineWidth*index>scrollWidth-halfWidth-_lineWidth/2){
[self setContentOffset:CGPointMake(scrollWidth-halfWidth*2, 0) animated:YES];
}
else{
[self setContentOffset:CGPointMake(leftSpace+_lineWidth/2, 0) animated:YES];
}
}
-(void)changeScrollOfSet:(NSInteger)index offX:(float)offX
{
[_currentBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
UIButton *button = (UIButton *)[self viewWithTag:index+100];
_currentBtn = button;
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
float halfWidth = CGRectGetWidth(self.frame)/2.0;
float scrollWidth = self.contentSize.width;
if(index*_lineWidth<halfWidth-_lineWidth/2){
[self setContentOffset:CGPointMake(0, 0) animated:NO];
}
else if(_lineWidth*index>scrollWidth-halfWidth-_lineWidth/2){
[self setContentOffset:CGPointMake(scrollWidth-halfWidth*2, 0) animated:NO];
}
else{
[self setContentOffset:CGPointMake(offX*_lineWidth-halfWidth+_lineWidth/2, 0) animated:NO];
}
}
-(void)changeLine:(float)offset{
CGRect rect = _line.frame;
rect.origin.x = offset*_lineWidth;
_line.frame = rect;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
float offset = scrollView.contentOffset.x;
if(offset>0){
offset = offset/CGRectGetWidth(scrollView.frame);
[self changeScrollOfSet:[self changeProgressToInteger:offset] offX:offset];
[self changeLine:offset];
}
}
//-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
// float offset = scrollView.contentOffset.x;
// if(offset>=0){
// offset = offset/CGRectGetWidth(scrollView.frame);
// NSInteger current = [self changeProgressToInteger:offset];
// [self changeScrollOfSet:current];
// }
//}
@end
使用方式如下:
indicator = [ScrollViewIndicator initWithTitles:titles pages:scroll];
第一个参数为传入的标题数组,第二个参数是外部的scrollview。