ScrollView小记
常用代理方法:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
只有 [self.scrolView setContentOffset:CGPointMake(0, 100) animated:true]; animated 为true 才会调用
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
刚开始拖动的时候,dragging 为 YES,decelerating 为 NO;decelerate 过程中,dragging 和 decelerating 都为 YES;decelerate 未结束时开始下一次拖动,dragging 和 decelerating 依然都为 YES。所以无法简单通过 table view 的 dragging 和 decelerating 判断是在用户拖动还是减速过程。
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
self.isUserDragging = true;//标记用户开始拖动
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
如果decelerate为0 则下面的两个方法不会调用
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
self.isUserDragging = false;//停止拖动
}
scrollViewDidEndDragging 中的decelerate为false 则不会调用
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
NSLog(@"--will decelerate ---");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
NSLog(@"--end decelerate ---");
}
返回可以进行缩放的视图
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
分页功能:
1.self.scrolView.pagingEnabled
2.

如图,scrollview 只有一个子视图content view ,这样只需在content view 中布局需要展示的view 即可
self.scrolView.clipsToBounds = false //设置false 这样就能显示超出scrolview 边界部分的视图 但超出部分无法响应触摸事件,需另行处理
先定义每个item的size
#define DIMATER 80 //宽高
#define PADDING 20 //间距
设置scrollview的宽度
self.scrolWidth.constant = DIMATER+2*PADDING;
设置content view的宽度为scrollview的N倍即可
int total = 10;
self.contentWidth.constant = self.scrolWidth.constant *total;
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
CGFloat targetX = targetContentOffset->x;
int index = roundf(targetX/(PADDING*2+DIMATER));
//直接改变目标x坐标
targetContentOffset->x = index*(PADDING*2+DIMATER);
}
视图的布局:
for (UIView *view in self.conentView.subviews) {
[view removeFromSuperview];
}
for (int i = 0; i < total; i ++) {
CGFloat y = (self.scrolView.frame.size.height - DIMATER)/2;
CGFloat x = i * ( DIMATER+2*PADDING ) + PADDING;
UILabel *lab = [UILabel new];
lab.frame = CGRectMake(x, y, DIMATER, DIMATER);
lab.text = [NSString stringWithFormat:@"#%d",i];
lab.textColor = [UIColor blackColor];
lab.textAlignment = NSTextAlignmentCenter;
lab.backgroundColor = [UIColor greenColor];
lab.layer.cornerRadius = DIMATER/2;
lab.layer.masksToBounds = true;
[self.conentView addSubview:lab];
}
效果:


实现多控制器的重用:
思路:加载屏幕左中右三个控制器,这样技能实现重用控制器的目的,而且在滑动的时候由于左右的控制器已经加载,用户体验会更加好
@property (strong, nonatomic) NSMutableArray* visibleItemsArr; //当前可用
@property (strong, nonatomic) NSMutableArray* reuseItemsArr;//缓存控制器
直接上代码:
- (void)setPages{
int total = 10;//假设共有十个控制器
//scrollview的子视图content view管理各个控制器的view
self.contentViewWidthConstraint.constant = self.scrolView.frame.size.width*total;
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}
- (void)loadPages:(NSInteger)page{
//加载左中右三个控制器
NSMutableArray *waitToLoadsArr = [@[@(page-1),@(page),@(page+1)] mutableCopy];
NSMutableArray *waitEnqueArr = [NSMutableArray array];
for (ReuseItemController *itemCon in self.visibleItemsArr) {
if ([waitToLoadsArr containsObject:itemCon.pageIndex]) {//无需再次加载
[waitToLoadsArr removeObject:itemCon.pageIndex];
}
else{//不需要加载了 放入缓存
[waitEnqueArr addObject:itemCon];
}
}
//从可用中移除 放入缓存
for (ReuseItemController *itemCon in waitEnqueArr) {
[itemCon.view removeFromSuperview];
[self.visibleItemsArr removeObject:itemCon];
[self.reuseItemsArr addObject:itemCon];
}
for (NSNumber *page in waitToLoadsArr) {
[self addController:page.integerValue];
}
}
- (void)addController:(NSInteger)page{
if (page<0 || page>(10-1)) {
return;
}
ReuseItemController *itemCon = [self dequePage:page];
itemCon.pageIndex = @(page);
itemCon.view.frame = CGRectMake(page*self.scrolView.frame.size.width, 0, self.scrolView.frame.size.width, self.scrolView.frame.size.height);
[self.contentView addSubview:itemCon.view];
[itemCon reloadData];
[self.visibleItemsArr addObject:itemCon];
}
//从缓存池中取 ,没有就直接新建
- (ReuseItemController*)dequePage:(NSInteger)page{
ReuseItemController *itemCon = [self.reuseItemsArr firstObject];
static int instance = 0;//标记是第几个实例 本例中instance = 0 ,1 ,2共三个
if (itemCon) {
[self.reuseItemsArr removeObject:itemCon];//rmeove
}
else {
itemCon = [ReuseItemController reuseItemController];
itemCon.instanceNum = @(instance);
instance++;
[itemCon willMoveToParentViewController:self];
//当前控制器作为子控制的容器
[self addChildViewController:itemCon];
[itemCon didMoveToParentViewController:self];
}
return itemCon;
}
//
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
int index = roundf(scrollView.contentOffset.x/self.scrolView.frame.size.width);
[self loadPages:index];
}
ScrollView小记的更多相关文章
- [原]Paste.deploy 与 WSGI, keystone 小记
Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...
- ScrollView嵌套ListView,GridView数据加载不全问题的解决
我们大家都知道ListView,GridView加载数据项,如果数据项过多时,就会显示滚动条.ScrollView组件里面只能包含一个组件,当ScrollView里面嵌套listView,GridVi ...
- Android ScrollView监听滑动到顶部和底部的两种方式(你可能不知道的细节)
Android ScrollView监听滑动到顶部和底部,虽然网上很多资料都有说,但是不全,而且有些细节没说清楚 使用场景: 1. 做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动 ...
- React-Native学习系列(二) Image和ScrollView
接下来,我们接着(一)继续讲,今天我们学习的是Image组件和ScrollView组件. Image组件 Image:一个用于显示多种不同类型图片的React组件.那么要如何使用呢? 引入本地图片: ...
- iOS学习笔记——滚动视图(scrollView)
滚动视图:在根视图中添加UIScrollViewDelegate协议,声明一些对象属性 @interface BoViewController : UIViewController<UIScro ...
- 实现下来ScrollView放大轮播图
创建工程,创建一个UIScrollView属性,并遵循其协议: #define kWidth self.view.frame.size.width//屏幕宽 #define kHeight self. ...
- React Native之 ScrollView介绍和使用
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
- ScrollView分栏视图分析
代码精华部分如下: //1.添加scrollView /* 1). 添加一个scrollView; 2).创建关注.热门.附近三个控制器. 3). 存储它们的名字到数组中,遍历并放到本控制器里. 4) ...
- IOS实现自动循环滚动广告--ScrollView的优化和封装
一.问题分析 在许多App中,我们都会见到循环滚动的视图,比如广告,其实想实现这个功能并不难,用ScrollView就可以轻松完成,但是在制作的过程中还存在几个小问题,如果能够正确的处理好这些小问题, ...
随机推荐
- C2678 二进制“>>”: 没有找到接受“std::stringstream”类型的左操作数的运算符(或没有可接受的转换)
C2678 二进制“>>”: 没有找到接受“std::stringstream”类型的左操作数的运算符(或没有可接受的转换)
- python import注意事项
# 基本概念 ## 模块&包简介 模块:所谓模块就是一个.py文件,用来存放变量,方法的文件,便于在其他python文件中导入(通过import或from).包(package): 包是更大的 ...
- Linux记录-史上最全的MySQL高性能优化实战总结(转载)
史上最全的MySQL高性能优化实战总结! 1.1 前言 MySQL对于很多Linux从业者而言,是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优 ...
- ABAP DEMO ole示例程序
*&---------------------------------------------------------------------* *& Report YCX_021 * ...
- 英雄联盟测试静态IP(固态IP)和动态IP的网速测试
在自己家里测试的,平时用迅雷下载大约600KB/S.同时,设置成动态IP的话,英雄联盟的延迟大约在100ms左右,如果设置成静态IP的话,大约是50ms左右,不过也有可能和DNS服务器的设置成静态有关 ...
- 安装本地 jar 文件
Maven 提供了 maven-install-plugin 可将 jar 文件安装至本地 repository.安装命令如下: mvn install:install-file -Dfile= -D ...
- yarn 的常用命令
初始化新项目yarn init添加依赖包yarn add [package]yarn add [package]@[version]yarn add [package]@[tag]将依赖项添加到不同依 ...
- php面向对象(文件操作)
文件操作 1.只能操作服务器的文件 2.文件包含目录和文件 判断文件类型 var_dump(filetype("../0529")); //返回文件的类型:目录dir 文件file ...
- 6.2.3 reginst中的yzm
@RequestMapping("/reginst/{yzm}") public Object reginst(User user,@PathVariable String yzm ...
- 转录组组装软件stringtie
StringTie是約翰·霍普金斯大學计算机生物中心开发的一款转录组组装软件,在组装转录本的完整度,精度和速度方面都较以往的cufflinks 有很大的提升,也是目前有参考基因组转录组主流的组装软件. ...