很长一段时间没有写博客了,最近在学习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页面和顶部标签页水平滚动效果的更多相关文章

  1. ActionBar+Fragment实现顶部标签页

    用ActionBar的TABS模式,和Fragment实现程序顶部的标签页切换. 一. MainActivity         public class MainActivity extends A ...

  2. iOS:UIScrollView控件和UIPageControl控件的详解

    UIScrollView滚动视图控件和UIPageControl分页视图控件:    UIScrollView用于显示多于一个屏幕的内容,超出屏幕范围的内容可以通过滑动进行查看,当然UIPagecon ...

  3. iOS - UIScrollView

    前言 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIScrollView : UIView <NSCoding> @available(iOS 2.0, ...

  4. IOS UIScrollView常用代理方法

    iOS UIScrollView代理方法有很多,从头文件中找出来学习一下 //只要滚动了就会触发 - (void)scrollViewDidScroll:(UIScrollView *)scrollV ...

  5. fastclick使用与 fastclick ios11.3相关bug原因(ios输入框点击变得不灵敏,ios input失焦后,页面上移,点击不了)

    FastClick 移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击.为了能够立即响应用户的点击事件,就有了FastClick. 安装fastc ...

  6. iOS UIScrollView的使用

    一.为什么要用UIScrollView? 移动设备的屏幕大小是极其有限的,因此直接展示在用户眼前的内容也相当有限当展示的内容较多,超出一个屏幕时,用户可通过滚动手势来查看屏幕以外的内容普通的UIVie ...

  7. iOS开发笔记13:顶部标签式导航栏及下拉分类菜单

    当内容及分类较多时,往往采用顶部标签式导航栏,例如网易新闻客户端的顶部分类导航,最近刚好有这样的应用场景,参考网络上一些demo,实现了这种导航效果,记录一些要点. 效果图(由于视频转GIF掉帧,滑动 ...

  8. css整个页面离顶部的距离

    body { padding:0; margin:0; font-size:12px; line-height:22px; } 说明: 整个页面离顶部的距离是22像素

  9. js——页面回到顶部

    很久都没有去慕课网学习学习了,刚恰好就看见了一个用的比较多的小例子——页面回到顶部,记得之前自己也是在初学web时,被这个坑了一回,因此今天特地拿来分享分享…… <!DOCTYPE html&g ...

随机推荐

  1. CSS中一些不经意的细节问题1

    CSS这样的语法,细节问题非常多,往往一些难以处理的问题,有可能是一些细节问题不到位,所以先记下一些,留给以后自己看看. 1.line-height:150%与line-height:1.5 的区别 ...

  2. atitit.表单验证 的dsl 本质跟 easyui ligerui比较

    atitit.表单验证的dsl 本质跟 easyui ligerui比较 1. DSL 声明验证 1 2. 自定义规则 1 3. 正则表达式验证,可以扩展实现 2 4. 犯错误消息提示,generic ...

  3. Liferay7 BPM门户开发之34: liferay7对外服务类生成(RestService Get Url)

    在liferay7中开发不依赖Service Builder的对外服务类,非常简洁,只需要2点注解: 在类的前部定义: @ApplicationPath("/PathXXX") 方 ...

  4. Inno Setup使用技巧

    一.关于Inno Setup如何在安装时播放音乐 方法(1): 在脚本编译里的[Code]与[Files]段处添加以下代码: [Code] Function mciSendString(lpszCom ...

  5. JSP九大内置对象详细介绍

    内置对象的特点: 1.由JSP规范提供,不用编写者实例化. 2.通过Web容器实现和管理 3. 所有JSP页面均可使用 4.只有在脚本元素的表达式或代码段中才可使用(<%=使用内置对象%> ...

  6. android ormlite queryBuilder.where() 多条件

    QueryBuilder<VideoTagInfo, Integer> queryBuilder = videoTagInfoIntegerDao.queryBuilder();try { ...

  7. vector的 emplace 和 insert 以及使用vector进行iterator遍历 且 erase的时候注意事项

    vector<int> first;//Size()==2 first.push_back(); first.push_back(); //first.insert(2); vector& ...

  8. easy datagrid 按钮控制

    onBeforeLoad : function() {// 这里是紧接着你的修改按钮的 // 注意ID为你初始化工具栏按钮对应的ID var adminid=<%=Admin_Id%>+' ...

  9. 连接UI到代码

    本章,你将连接FoodTracker应用程序的UI到代码并定义一些可执行的动作.当你完成时,你的应用程序将是这个样子: 学习目标在课程结束时,你将能够:1.解释一个storyboard中的场景和vie ...

  10. 如何提高nodejs程序的稳定性,健壮性

    在网上看到一些帖子,吐糟,质疑nodejs 程序的稳定性,为什么呢?其一,可能这个和javascript有关吧,node是拿javascript去实现的,而javascript又被称为是“世界上误解最 ...