IOS UIScrollView + UIButton 实现segemet页面和顶部标签页水平滚动效果
很长一段时间没有写博客了,最近在学习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(, , SCROLLVIEW_WIDTH, SEGEMENT_HEIGTHT) titleArray:titleArray block:^void(int index){ //用block实现回调,顶部按钮点击的时候滚动到指定位置
[_myScrollView setContentOffset:CGPointMake((index - ) * SCROLLVIEW_WIDTH, )];
}];
}
[self addSubview:_mySegementView];
[self addSubview:self.myScrollView]; if (self) {
for (int i = ; i < viewArray.count; i++) {
UIViewController *viewController = viewArray[i];
viewController.view.frame = CGRectMake(i * SCROLLVIEW_WIDTH, , SCROLLVIEW_WIDTH, self.myScrollView.frame.size.height);
[self.myScrollView addSubview:viewController.view];
}
self.myScrollView.contentSize = CGSizeMake(viewArray.count * SCROLLVIEW_WIDTH, );
} return self;
} // 滚动页面视图懒加载
- (UIScrollView *)myScrollView
{
if (_myScrollView == nil) {
_myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(, _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 + ];
}
} @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:]];
self.block = clickedBlock;
nPageIndex = ;
titleCount = titleArray.count;
btnArray = [NSMutableArray array];
for (int i = ; i < titleCount; i++) {
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(i * SEGEMENT_BTN_WIDTH, , SEGEMENT_BTN_WIDTH, )];
[btn setTitle:titleArray[i] forState:UIControlStateNormal];
btn.titleLabel.font = [UIFont fontWithName:@"Arial" size:];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
btn.tag = i + ;
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
[self.segementScrollView addSubview:btn];
[btnArray addObject:btn];
}
self.selectedLine.frame = CGRectMake(, , SEGEMENT_BTN_WIDTH, );
[self.segementScrollView addSubview: self.selectedLine];
self.segementScrollView.contentSize = CGSizeMake(titleCount * SEGEMENT_BTN_WIDTH, );
}
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, ) animated:YES];
}
else if (currentBtn.frame.origin.x < self.segementScrollView.contentOffset.x)
{
[self.segementScrollView setContentOffset:CGPointMake(currentBtn.frame.origin.x, ) animated:YES];
} //下方选中标记线条滚动效果
[UIView animateWithDuration:0.2 animations:^{
_selectedLine.frame = CGRectMake(currentBtn.frame.origin.x, self.frame.size.height - , SEGEMENT_BTN_WIDTH, );
}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 = ; i < ; i++) {
MyViewController1 *viewController1 = [[MyViewController1 alloc] initWithIndex:i + ];//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
IOS UIScrollView + UIButton 实现segemet页面和顶部标签页水平滚动效果的更多相关文章
- ActionBar+Fragment实现顶部标签页
用ActionBar的TABS模式,和Fragment实现程序顶部的标签页切换. 一. MainActivity public class MainActivity extends A ...
- iOS:UIScrollView控件和UIPageControl控件的详解
UIScrollView滚动视图控件和UIPageControl分页视图控件: UIScrollView用于显示多于一个屏幕的内容,超出屏幕范围的内容可以通过滑动进行查看,当然UIPagecon ...
- iOS - UIScrollView
前言 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIScrollView : UIView <NSCoding> @available(iOS 2.0, ...
- IOS UIScrollView常用代理方法
iOS UIScrollView代理方法有很多,从头文件中找出来学习一下 //只要滚动了就会触发 - (void)scrollViewDidScroll:(UIScrollView *)scrollV ...
- fastclick使用与 fastclick ios11.3相关bug原因(ios输入框点击变得不灵敏,ios input失焦后,页面上移,点击不了)
FastClick 移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击.为了能够立即响应用户的点击事件,就有了FastClick. 安装fastc ...
- iOS UIScrollView的使用
一.为什么要用UIScrollView? 移动设备的屏幕大小是极其有限的,因此直接展示在用户眼前的内容也相当有限当展示的内容较多,超出一个屏幕时,用户可通过滚动手势来查看屏幕以外的内容普通的UIVie ...
- iOS开发笔记13:顶部标签式导航栏及下拉分类菜单
当内容及分类较多时,往往采用顶部标签式导航栏,例如网易新闻客户端的顶部分类导航,最近刚好有这样的应用场景,参考网络上一些demo,实现了这种导航效果,记录一些要点. 效果图(由于视频转GIF掉帧,滑动 ...
- css整个页面离顶部的距离
body { padding:0; margin:0; font-size:12px; line-height:22px; } 说明: 整个页面离顶部的距离是22像素
- js——页面回到顶部
很久都没有去慕课网学习学习了,刚恰好就看见了一个用的比较多的小例子——页面回到顶部,记得之前自己也是在初学web时,被这个坑了一回,因此今天特地拿来分享分享…… <!DOCTYPE html&g ...
随机推荐
- mongo(三)基本操作
mongo(三)基本操作 本文来自mongodb官方文档的部分翻译以及自己的理解. CRUD:增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delet ...
- 通过Anuglar Material串串学客户端开发 - NodeJS模块机制之Module.Exports
module.exports 前文讲到在Angular Material的第二个编译文件docs/gulpfile.js中却看到了一个奇怪的东西module.exports那么module.expor ...
- .NET通过RFC读取SAP数据
本篇文章中我主要讲的是.NET如何通过RFC从SAP中读取数据.为了功能的可复用性,我将调用RFC的代码从业务层中分离出来单独建立在一个namespace中. 当然除了需要我们自己编写代码以外,还需要 ...
- [数据库操作]Java中的JDBC的使用方法.
前言:想必大家在实际编码中都遇到过JDBC的操作, 这里仅做自己的一个总结, 有错误和不完整之处还请大家提出来. 1,JDBC其实一套规范(接口)数据库厂商需要实现此接口(实现类)--数据库驱动 2, ...
- C语言实现二叉树-03版
我们亲爱的项目经理真是有创意,他说你给我写得二叉树挺好的: 功能还算可以:插入节点,能够删除节点: 可是有时候我们只是需要查找树的某个节点是否存在: 所以我希望你能够给我一个find功能: 还有就是, ...
- C语言实现冒泡排序-整数排序
我一直觉得排序算法挺重要的,但是却没有深入的去理解它: 没有深入理解就无法用代码将它实现: 在腾讯的在线模拟考试中就有一题问到冒泡排序: 我几乎是傻眼了!我知道这样的问题是最基础的: 无论过去怎样现在 ...
- JS字符串
字符串 双引号""或单引号''包围的都是字符串. 创建字符串 直接用单引号或双引号包围. var str1="我的过去"; console.log(typeof ...
- paip.python NameError name 'xxx' is not defined\
paip.python NameError name 'xxx' is not defined\ 导入一个另一个文件里面的函数的时候儿,出孪这个err #这个仅仅导入孪file...要使用里面的fun ...
- LDR 和 ADR 彻底详解
0.什么是位指令? 答:伪指令(Pseudo instruction)是用于告诉汇编程序如何进行汇编的指令.它既不控制机器的操作也不被汇编成机器代码, 只能为汇编程序所识别并指导汇编如何进行. 1.L ...
- C#中的串口通信
关于串行接口 串行接口(Serial port)又称“串口”,主要用于串行式逐位数据传输.常见的有一般电脑应用的RS-232(使用 25 针或 9 针连接器)和工业电脑应用的半双工RS-485与全双工 ...