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就可以轻松完成,但是在制作的过程中还存在几个小问题,如果能够正确的处理好这些小问题, ...
随机推荐
- oracle 的自定义的存储函数遇到的 package or function is in an invalid state
转: oracle 的自定义的存储函数遇到的 package or function is in an invalid state 2017-10-28 11:08:17 major_tom 阅读数 ...
- 我的一个PLSQL存储过程【我】 改版,加入日志表
创建日志表sql: -- Create table create table PROCEDURE_LOG ( ID ) not null, NAME ), CODE NUMBER, MSG ), IN ...
- js Date.parse()时区问题
比较两个时间,parse() 方法可解析一个日期时间字符串,并返回 1970/1/1 午夜距离该日期时间的毫秒数.Date.parse时间多了8小时. 正确的方法: var nowDate = Dat ...
- 小程序报错 thirdScriptError
thirdScriptError sdk uncaught third Error Unexpected token export SyntaxError: Unexpected token expo ...
- Java 终于在 Java 8 中引入了 Lambda 表达式。也称之为闭包或者匿名函数。
本文首发于 blog.zhaochunqi.com 转载请注明 blog.zhaochunqi.com 根据JSR 335, Java 终于在 Java 8 中引入了 Lambda 表达式.也称之为闭 ...
- 【Leetcode_easy】849. Maximize Distance to Closest Person
problem 849. Maximize Distance to Closest Person solution1: class Solution { public: int maxDistToCl ...
- Teaset-React Native UI 组件库
GitHub地址 https://github.com/rilyu/teaset/blob/master/docs/cn/README.md React Native UI 组件库, 超过 20 个纯 ...
- SELinux安全子系统的学习
SELinux(Security-Enhanced Linux)是美国国家安全局在 Linux 开源社区的帮助下开发的 一个强制访问控制(MAC,Mandatory Access Control)的安 ...
- idea的maven依赖本地jar
可以手动添加jar,但是idea手动添加jar时,有时候不行. 用maven依赖本地jar方法,感觉比较正规,不会因为自己忘记手动添加jar. 比如这个达梦数据库依赖 <dependency&g ...
- jenkins publish .net core application to linux server
最近学习Docker与Jenkins, 网上大部分都是关于Jenkins+Git+Docker进行持续远程部署, 我一直在考虑为什么Jenkins和Docker要绑定一块使用, 因为我想单独使用Jen ...