常用代理方法:
- (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]; }