常用代理方法:

- (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]; }

最新文章

  1. ASP.NET中的缓存机制
  2. kendo-ui学习笔记(一)
  3. 关于容器为NavigationControlle时,view的起始位置的问题
  4. Android 之窗口小部件详解--App Widget
  5. Odoo误删除服务产品造成的错误解决办法
  6. sed初学
  7. linux 安装phpMyAdmin
  8. 关于K-Means算法
  9. fastjson初始化对性能的影响(转)
  10. doubango(5)--SIP协议栈传输层的启动
  11. FreeSWITCH 安装配置的 各种坑, 填坑
  12. JDBC01 利用JDBC连接数据库【不使用数据库连接池】
  13. JavaScript 知识图谱
  14. Tom DeMarco:软件工程这个概念已过时?
  15. B哥竟然也被裁了,聊一聊我的看法
  16. WPF 小小案列(同步异步)
  17. 智能化脚本autoit v3的简单了解
  18. PHP 生成器语法
  19. 解压版中文乱码问题MYSQL中文乱码
  20. [转]C++中vector使用详细说明

热门文章

  1. 数据分析入门——numpy
  2. Spring cloud微服务安全实战-_5-10实现基于session的SSO(Token有效期)
  3. 软件定义网络基础---SDN控制平面
  4. 算法习题---5.5集合栈计算机(Uva12096)*****
  5. Java Class与反射相关的一些工具类
  6. 如何切换svn的登陆账号?
  7. ANSI转义序列
  8. 转 Zabbix 3.2.6通过SNMP和iDRAC监控DELL服务器
  9. idea中报Can&#39;t start Git: git.exe The path to Git executable is probably not valid. Fix it
  10. 【linux学习笔记三】链接命令