您的位置:首页 > 产品设计 > UI/UE

IOS UIScrollView + UIButton 实现segemet页面和顶部标签页水平滚动效果

2016-06-29 11:39 866 查看
  很长一段时间没有写博客了,最近在学习iOS开发,看了不少的代码,自己用UIScrollView和UIButton实现了水平滚动的效果,有点类似于今日头条的主界面框架,效果如下:


代码如下:

MyScrollView.h

#import <UIKit/UIKit.h>
#import "MySegementView.h"

@interface MyScrollView : UIView<UIScrollViewDelegate>

- (instancetype) initWithFrame:(CGRect)frame titleArray:(NSArray *)titleArray viewArray:(NSArray *)viewArray;

//滚动页面
@property (strong, nonatomic)UIScrollView *myScrollView;

//顶部标签按钮滚动视图
@property (strong, nonatomic)MySegementView *mySegementView;

@end


MyScrollView.m

#define SCROLLVIEW_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCROLLVIEW_HEIGTH self.bounds.size.height
#define SEGEMENT_HEIGTHT 44

#import "MyScrollView.h"

@implementation MyScrollView

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/

- (instancetype) initWithFrame:(CGRect)frame titleArray:(NSArray *)titleArray viewArray:(NSArray *)viewArray
{
self = [super initWithFrame:frame];
if (_mySegementView == nil) {
_mySegementView = [[MySegementView alloc] initWithFrame:CGRectMake(0, 0, SCROLLVIEW_WIDTH, SEGEMENT_HEIGTHT) titleArray:titleArray block:^void(int index){  //用block实现回调,顶部按钮点击的时候滚动到指定位置
[_myScrollView setContentOffset:CGPointMake((index - 1) * SCROLLVIEW_WIDTH, 0)];
}];
}
[self addSubview:_mySegementView];
[self addSubview:self.myScrollView];

if (self) {
for (int i = 0; i < viewArray.count; i++) {
UIViewController *viewController = viewArray[i];
viewController.view.frame = CGRectMake(i * SCROLLVIEW_WIDTH, 0, SCROLLVIEW_WIDTH, self.myScrollView.frame.size.height);
[self.myScrollView addSubview:viewController.view];
}
self.myScrollView.contentSize = CGSizeMake(viewArray.count * SCROLLVIEW_WIDTH, 0);
}

return self;
}

// 滚动页面视图懒加载
- (UIScrollView *)myScrollView
{
if (_myScrollView == nil) {
_myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, _mySegementView.frame.size.height, SCROLLVIEW_WIDTH, SCROLLVIEW_HEIGTH - _mySegementView.frame.size.height)];
_myScrollView.backgroundColor = [UIColor clearColor];
_myScrollView.delegate = self;
_myScrollView.showsVerticalScrollIndicator = NO;
_myScrollView.showsHorizontalScrollIndicator = NO;
_myScrollView.bounces = NO;
_myScrollView.scrollsToTop = NO;
_myScrollView.pagingEnabled = YES;

}
return _myScrollView;
}

//滚动结束,更新按钮下方线条
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (scrollView==_myScrollView)
{
int p=_myScrollView.contentOffset.x / SCROLLVIEW_WIDTH;
[_mySegementView setPageIndex:p + 1];
}
}

@end


MySegementView.h

#import <UIKit/UIKit.h>

typedef void (^btnClickedBlock)(int index);

@interface MySegementView : UIView<UIScrollViewDelegate>
{
int nPageIndex;
int titleCount;
UIButton *currentBtn;
NSMutableArray *btnArray;
}

- (void)setPageIndex:(int)nIndex;

- (instancetype) initWithFrame:(CGRect)frame titleArray : (NSArray *)titleArray block : (btnClickedBlock) clickedBlock;

@property (nonatomic, copy) btnClickedBlock block;

@property (strong, nonatomic) UIScrollView *segementScrollView;

@property (strong, nonatomic) UIView *selectedLine;

@end


MySegementView.m

#import "MySegementView.h"
#define SEGEMENT_BTN_WIDTH 48

@implementation MySegementView

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (instancetype) initWithFrame:(CGRect)frame titleArray : (NSArray *)titleArray block : (btnClickedBlock) clickedBlock
{
self = [super initWithFrame:frame];
[self addSubview:self.segementScrollView];
if (self) {
[self setBackgroundColor:[UIColor colorWithRed:0x2d/255.0 green:0x2a/255.0 blue:0x2b/255.0 alpha:1]];
self.block = clickedBlock;
nPageIndex = 1;
titleCount = titleArray.count;
btnArray = [NSMutableArray array];
for (int i = 0; i < titleCount; i++) {
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(i * SEGEMENT_BTN_WIDTH, 0, SEGEMENT_BTN_WIDTH, 42)];
[btn setTitle:titleArray[i] forState:UIControlStateNormal];
btn.titleLabel.font = [UIFont fontWithName:@"Arial" size:14];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
btn.tag = i + 1;
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
[self.segementScrollView addSubview:btn];
[btnArray addObject:btn];
}
self.selectedLine.frame = CGRectMake(0, 42, SEGEMENT_BTN_WIDTH, 2);
[self.segementScrollView addSubview: self.selectedLine];
self.segementScrollView.contentSize = CGSizeMake(titleCount * SEGEMENT_BTN_WIDTH, 0);
}
return self;
}

//懒加载
- (UIScrollView *)segementScrollView
{
if (_segementScrollView == nil) {
CGRect rect = self.frame;
_segementScrollView = [[UIScrollView alloc] initWithFrame:rect];
_segementScrollView.showsHorizontalScrollIndicator = NO;
_segementScrollView.showsVerticalScrollIndicator = NO;
_segementScrollView.bounces = NO;
_segementScrollView.pagingEnabled = NO;
_segementScrollView.delegate = self;
_segementScrollView.scrollsToTop = NO;
}
return _segementScrollView;
}

//懒加载
- (UIView *)selectedLine
{
if (_selectedLine == nil) {
_selectedLine = [[UIView alloc] init];
_selectedLine.backgroundColor = [UIColor redColor];
}
return _selectedLine;
}

//设置当前页面,并更新顶部标签页
- (void)setPageIndex:(int)nIndex
{
if (nIndex != nPageIndex) {
nPageIndex = nIndex;
[self refreshSegement];
}
}

- (void)refreshSegement
{
//找到当前选中页面对应的顶部按钮
for (UIButton *btn in btnArray) {
if (btn.tag == nPageIndex) {
currentBtn = btn;
}
}

//如果选中页面对应按钮超出可视范围,顶部滚动视图滚动
int x = currentBtn.frame.origin.x;
if (currentBtn.frame.origin.x + SEGEMENT_BTN_WIDTH > self.frame.size.width + self.segementScrollView.contentOffset.x) {
[self.segementScrollView setContentOffset:CGPointMake(self.segementScrollView.contentOffset.x + SEGEMENT_BTN_WIDTH, 0) animated:YES];
}
else if (currentBtn.frame.origin.x < self.segementScrollView.contentOffset.x)
{
[self.segementScrollView setContentOffset:CGPointMake(currentBtn.frame.origin.x, 0) animated:YES];
}

//下方选中标记线条滚动效果
[UIView animateWithDuration:0.2 animations:^{
_selectedLine.frame = CGRectMake(currentBtn.frame.origin.x, self.frame.size.height - 2, SEGEMENT_BTN_WIDTH, 2);
}completion:^(BOOL finished) {

}];
}

- (void)btnClick:(UIButton*)btn
{
currentBtn = btn;
if (nPageIndex != btn.tag) {
nPageIndex = btn.tag;
[self refreshSegement];
self.block(nPageIndex);
}
}
@end


使用方法:

- (void)viewDidLoad {
[super viewDidLoad];

NSMutableArray *array=[NSMutableArray array];//显示的标签页
for (int i = 0; i < 12; i++) {
MyViewController1 *viewController1 = [[MyViewController1 alloc] initWithIndex:i + 1];//initWithIndex : 自定义的构造方法,用于显示页面编号
[array addObject:viewController1];//滚动视图列表
}
myScrollView = [[MyScrollView alloc] initWithFrame:self.view.frame titleArray:@[@"第1页",@"第2页",@"第3页",@"第4页",@"第5页",@"第6页",@"第7页",@"第8页",@"第9页",@"第10页",@"第11页",@"第12页"] viewArray:array];

[self.view addSubview:myScrollView];
// Do any additional setup after loading the view, typically from a nib.
}


源码下载链接:http://download.csdn.net/detail/lzm2625347497/9562677
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: