iOS用AutoLayout实现分页滚动功能

滚动视图分页

UIScrollView的pagingEnabled属性用于控制是否按分页进行滚动。在一些应用中会应用到这一个特性,最典型的就是手机桌面的应用图标列表。这些界面中往往每一页功能都比较独立,系统也提供了UIPageViewController来实现这种分页滚动的功能。

实现分页滚动的UI实现一般是最外层一个UIScrollView。然后UIScrollView里面是一个总体的容器视图containerView。容器视图添加N个页视图,对于水平分页滚动来说容器视图的高度和滚动视图一样,而宽度则是滚动视图的宽度乘以页视图的数量,页视图的尺寸则和滚动视图保持一致,对于垂直分页滚动来说容器视图的宽度和滚动视图一样,而高度则是滚动视图的高度乘以页视图的数量,页视图的尺寸则和滚动视图保持一致。每个页视图中在添加各自的条目视图。

整体效果图如下:

MyLayout实现分页滚动的方法

你也可以用MyLayout布局库来实现分页滚动的能力。MyLayout布局库是笔者开源的一套功能强大的UI布局库。

您可以从github地址: github.com/youngsoft/M… 下载或者从podfile中导入:

pod 'MyLayout'

来使用MyLayout。下面是具体用MyLayout来实现分页滚动的代码。

//
#import <MyLayout.h>

- (void)loadView {

 UIScrollView *scrollView = [[UIScrollView alloc] init];
 if (@available(iOS 11.0,*)) {
 scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
 } else {
 // Fallback on earlier versions
 }
 scrollView.pagingEnabled = YES;
 scrollView.backgroundColor = [UIColor whiteColor];
 self.view = scrollView;

 //建立一个水平线性布局容器视图
 MyLinearLayout *containerView = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Horz];
 containerView.myVertMargin = 0; //水平线性布局的上下边界和滚动视图保持一致,这里也会确定线性布局的高度。
 containerView.gravity = MyGravity_Vert_Fill | MyGravity_Horz_Fill; //设置线性布局中的所有子视图均分和填充线性布局的高度和宽度。
 [scrollView addSubview:containerView];

 //添加页视图
 NSArray<UIColor*> *colors = @[[UIColor redColor],[UIColor blueColor]];
 NSMutableArray<UIView*> *pageViews = [NSMutableArray arrayWithCapacity:colors.count];
 for (int i = 0; i < colors.count; i++)
 {
 //建立页视图
 UIView *pageView = [UIView new];
 pageView.backgroundColor = colors[i];
 [containerView addSubview:pageView];

 //因为线性布局通过属性gravity的设置就可以确定子页视图的高度和宽度,再加上线性布局的特性,所以页视图不需要设置任何附加的约束。

 [pageViews addObject:pageView];

 }

 //关键的一步,设置线性布局的宽度是滚动视图的倍数
 containerView.widthSize.equalTo(scrollView.widthSize).multiply(colors.count);

 //这里可以为每个页视图添加不同的条目视图,具体实现大家自行添加代码吧。

}

MyLayout实现桌面的图标列表分页功能

MyLayout中的流式布局MyFlowLayout所具备的能力和flex-box相似,甚至有些特性要强于后者。流式布局用于一些子视图有规律排列的场景,就比如本例子中的滚动分页的图标列表的能力。下面就是具体的实现代码。

- (void)loadView {

 UIScrollView *scrollView = [[UIScrollView alloc] init];
 if (@available(iOS 11.0,*)) {
  scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
 } else {
  // Fallback on earlier versions
 }
 scrollView.pagingEnabled = YES;
 scrollView.backgroundColor = [UIColor whiteColor];
 self.view = scrollView;

 //建立一个垂直数量约束流式布局:每列展示3个子视图,每页展示9个子视图,整体从左往右滚动。
 MyFlowLayout *containerView = [MyFlowLayout flowLayoutWithOrientation:MyOrientation_Vert arrangedCount:3];
 containerView.pagedCount = 9; //pagedCount设置为非0时表示开始分页展示的功能,这里表示每页展示9个子视图,这个数量必须是arrangedCount的倍数。
 containerView.wrapContentWidth = YES; //设置布局视图的宽度由子视图包裹,当垂直流式布局的这个属性设置为YES,并和pagedCount搭配使用会产生分页从左到右滚动的效果。
 containerView.myVertMargin = 0; //容器视图的高度和滚动视图保持一致。

 containerView.subviewHSpace = 10;
 containerView.subviewVSpace = 10; //设置子视图的水平和垂直间距。
 containerView.padding = UIEdgeInsetsMake(5,5,5); //布局视图的内边距设置。
 [scrollView addSubview:containerView];

 //建立条目视图
 for (int i = 0; i < 40; i++)
 {
  UILabel *label = [UILabel new];
  label.textAlignment = NSTextAlignmentCenter;
  label.backgroundColor = [UIColor greenColor];
  label.text = [NSString stringWithFormat:@"%d",i];
  [containerView addSubview:label];
 }

 //获取流式布局的横屏size classes,并且设置设备处于横屏时,每排数量由3个变为6个,每页的数量由9个变为18个。
 MyFlowLayout *containerViewSC = [containerView fetchLayoutSizeClass:MySizeClass_Landscape copyFrom:MySizeClass_wAny | MySizeClass_hAny];
 containerViewSC.arrangedCount = 6;
 containerViewSC.pagedCount = 18;

从上面的代码可以看出要实现分页滚动的图标列表的能力,主要是对充当容器视图的流式布局设置一些属性即可,不需要为条目设置任何约束,而且还支持横竖屏下每页的不同数量的展示能力。整个功能代码量少,对比用UICollectionView来实现相同的功能要简洁和容易得多。下面是程序运行的效果:

微信公众号搜索 “ 程序精选 ” ,选择关注!
精选程序员所需精品干货内容!