标签:
上一篇VFL(Visual format language)的文章中讲了一些基本用法.传送门http://www.cnblogs.com/wupei/p/4150626.html.
这篇简单的讲解下UIScrollView下的自动布局.UIScrollView有一个contentSize所以,他跟其他的view不一样。其他的view你只需要指定他的四个边距,或者能固定他的大小就行。但是UIScrollView不行,约束写不好可能会导致滚动不了,或者报错或一堆警告。但是理解了他的原理就很容易去做到了。
一、首先实现一个水平滚动
水平滚动最常见的就是一个广告循环了(此处不讲解循环),以前通常是直接用宽度乘以几就是contenSize的宽度。这里就用自动布局来实现指定contenSize的宽度.代码如下:
UIScrollView *scrollview=[[UIScrollView alloc]init]; scrollview.translatesAutoresizingMaskIntoConstraints=NO; [self.view addSubview:scrollview]; scrollview.pagingEnabled=YES; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollview]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(scrollview)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollview]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(scrollview)]]; UIView *view1=[[UIView alloc]init]; view1.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view1]; view1.backgroundColor=[UIColor redColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view1(==width)]" options:0 metrics:@{@"width":@(self.view.frame.size.width)} views:NSDictionaryOfVariableBindings(view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view1(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view1)]]; UIView *view2=[[UIView alloc]init]; view2.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view2]; view2.backgroundColor=[UIColor grayColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view1][view2(==view1)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view2,view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view2(==view1)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view2,view1)]]; UIView *view3=[[UIView alloc]init]; view3.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view3]; view3.backgroundColor=[UIColor blackColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view2][view3(==view2)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3,view2)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view3(==view1)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3,view1)]];
这在段代码里,我给scrollview初始化了三个子view.而这三个子view在水平方向一字排开。我们来看一下这三个子view的水平约束
[scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view1(==width)]" options:0 metrics:@{@"width":@(self.view.frame.size.width)} views:NSDictionaryOfVariableBindings(view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view1][view2(==view1)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view2,view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view2][view3(==view2)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3,view2)]];
从这三个语句来看,很容易看出,这三个view,宽度是相等的。而且下一个view紧跟着上一个view的最右边。
在第一个view的约束中H:|[view1(==width)],这里的H:|就是表明这个view紧贴在它的spuerview的最左边。
第三个view的约束中H:[view2][view3(==view2)]|,后面有一个|,说明了view3在superview的最右边紧贴着。换句话说,这个view3的maxX就是contentSize的width.在这里也就起来一个约束他的滚动范围的作用。正是因为如果,我们的scrollview就可以愉快的滚动起来了。
二、实现一个垂直方向滚动
看过了水平方向的代码,我们知道,只要知道什么时候它的子view贴到最边上就可以确定它的滚动范围了。同理垂直方向也是一样。
UIScrollView *scrollview=[[UIScrollView alloc]init]; scrollview.translatesAutoresizingMaskIntoConstraints=NO; [self.view addSubview:scrollview]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollview]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(scrollview)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollview]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(scrollview)]]; UIView *view1=[[UIView alloc]init]; view1.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view1]; view1.backgroundColor=[UIColor redColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view1(==width)]|" options:0 metrics:@{@"width":@(self.view.frame.size.width)} views:NSDictionaryOfVariableBindings(view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view1(==300)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view1)]]; UIView *view2=[[UIView alloc]init]; view2.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view2]; view2.backgroundColor=[UIColor grayColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view2(==view1)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view2,view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view1][view2(==400)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view2,view1)]]; UIView *view3=[[UIView alloc]init]; view3.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view3]; view3.backgroundColor=[UIColor purpleColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view3(==view2)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3,view2)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view2][view3(==500)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3,view2)]];
我们再次把这三个view的垂直方向约束抽出来:
[scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view1(==300)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view1][view2(==400)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view2,view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view2][view3(==500)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3,view2)]];
这三个约束,很明显看出view1高度为300,view2高度为400,view3高度为500,而且它们都紧跟在着上一个view。
在view1的约束中可以看出来,它是最上面的,换句话说他的坐标就是(0,0).
而view3的约束是[view3(==500)]|,那它的maxY就是contenSize的height了.这样就可以确定他能在垂直方向滚动了。
三、两个方法都可以滚动(相信这一步已经不难了)
UIScrollView *scrollview=[[UIScrollView alloc]init]; scrollview.translatesAutoresizingMaskIntoConstraints=NO; [self.view addSubview:scrollview]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollview]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(scrollview)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollview]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(scrollview)]]; UIView *view1=[[UIView alloc]init]; view1.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view1]; view1.backgroundColor=[UIColor redColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view1(==width)]" options:0 metrics:@{@"width":@(self.view.frame.size.width)} views:NSDictionaryOfVariableBindings(view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view1(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view1)]]; UIView *view2=[[UIView alloc]init]; view2.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view2]; view2.backgroundColor=[UIColor grayColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view1][view2(==view1)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view2,view1)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view2(==view1)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view2,view1)]]; UIView *view3=[[UIView alloc]init]; view3.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view3]; view3.backgroundColor=[UIColor blackColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view2][view3(==view2)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3,view2)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view3(==view1)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3,view1)]]; UIView *view4=[[UIView alloc]init]; view4.translatesAutoresizingMaskIntoConstraints=NO; [scrollview addSubview:view4]; view4.backgroundColor=[UIColor yellowColor]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view4(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view4)]]; [scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view1][view4(==800)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view4,view1)]];
这里只要知道了两个方法什么时候是到底了,就可以确定他的contenSize了,所以,做起来也不会很麻烦。第三个就不再说一次了。
最后总结:在UIScrollView中使用自动布局,如果要想滚动,就要知道他的contenSize,这是大家都知道的。在自动布局中(VFL方式),你只需要知道你的H方向的范围,以及V方向的范围就可以实现效果。也就是知道|[view]|这个约束中的两个"|"的位置。有一点要注意的是,你的view的宽度你得知道,而且约束没有错。否则就不会算出来你的contenSize。如果H|[view]|这样是无法得知的,因为contenSize是没有范围的,他只知道这个view跟左右两这没有距离,但是无法得知具体width是多少。因为contenSize它自己也不知道它的width是多少。所以你这么写它就会对了H|[view(==x)]|,至于X值是多少,就看你实际情况了.
转载注明出处:http://www.cnblogs.com/wupei/p/4428164.html , http://zhiwupei.sinaapp.com/?p=64
Demo源码:https://github.com/zhiwupei/VFL/
在UIScrollView中使用Auto Layout中的VFL(Visual format language)
标签:
原文地址:http://www.cnblogs.com/wupei/p/4428164.html