使用Lay Out里面的VFL实现自动布局

来源:互联网 发布:网址正则表达式 js 编辑:程序博客网 时间:2024/05/29 09:13

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">今天我们讲到了UIViewController,然后就提到了一个横屏和竖屏的时候视图变化问题,刚开始我们学的是一个比较传统的方法,通过判断屏幕当前的状态然后在对view进行重新的调整。在学习的过程中,翔哥又给我们提到了一种新的方法VFL,并且用代码简单的实现了一下,然而并不是很懂。。。然后就自己在网上找了多篇对VFL的使用,不过都不是很明了。然后就自己就总结实践了一下,下面说一下我自己的使用方法。</span>

1.先创建两个类,LoginViewController和LoginView,父类分别是UIViewController和UIView。然后将LoginView挂到LoginViewController上。然后再LoginView中添加两个UILabel属性

2.当屏幕旋转的时候视图控制器会向他下面的LoginView发送一个消息,让视图进行重新布局。

3.在LoginView中对View重新布局

- (void)layoutSubviews{    [self addConstraints:(NSArray *)];}


从上面的布局方法中可以看到addConstraints:(NSArray *)需要一个NSArray类型的参数。而下面的方法返回类型正好是NSArray。所以就必须先了解下面的方法:


NSLayoutConstraint经常使用的一个方法

+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;

参数介绍:

format:字符串类型的。主要是用来约束屏幕在横竖的时候控件或view的位置尺寸的

opts:默认参数,默认写0;具体根据自己想实现的要求去选择枚举值

metrics:是一个字典,里面主要写一些format字符串中要使用到的参数。系统会自动的将format字符串中的参数  在metrics字典中查找和参数名相同的key值,然后使用key值对应得value值。如果,你使用metrics这个字典了,就必须保证format字符串能在里面找到这个key值,否则会报错。

views:又是一个字典。这里面是VFL中所有使用到的view。


对format字符串中的格式做一个了解

功能        表达式

水平方向          H:

垂直方向          V:

Views         [view]

SuperView      |

关系         >=,==,<=

空间,间隙       -

优先级        @value

代码实现:

在LoginView中添加两个UILabel属性,记得释放哦

#import <UIKit/UIKit.h>@interface LoginView : UIView@property (nonatomic , retain) UILabel *firstLabel;@property (nonatomic , retain) UILabel *secLabel;@end


在LoginView.m中进行实现:

第一种情况:

1.LoginView中只添加一个控件的时候,我们将firstLabel添加上去


// 布局视图- (void)addSubviews{    // 设置背景颜色    self.backgroundColor = [UIColor cyanColor];        // 添加firstLabel    self.firstLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 200, 30)];    self.firstLabel.layer.borderWidth = 1;    self.firstLabel.layer.borderColor = [[UIColor lightGrayColor] CGColor];    self.firstLabel.layer.cornerRadius = 5;    self.firstLabel.text = @"点我";    self.firstLabel.textAlignment = NSTextAlignmentCenter;        [self addSubview:self.firstLabel];    [self.firstLabel release];}#pragma mark - 屏幕旋转方法的实现- (void)layoutSubviews{        UILabel *fl = self.firstLabel;        fl.translatesAutoresizingMaskIntoConstraints = NO;// 这个必须写否则下面的约束方法不起作用      //firstLabel控件约束    // 水平方向上的约束    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[fl]-50-|" options:0 metrics:nil views:@{@"fl":fl}]];    //垂直方向上的约束    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[fl(==30)]" options:0 metrics:nil views:@{@"fl":fl}]];      }

对约束方法解析:

<span style="color:#ff0000;">@"H:|-50-[fl]-50-|"</span><span style="color: rgb(37, 37, 37); font-family: 'Helvetica Neue', Helvetica, STheiti, 微软雅黑, 黑体, Arial, Tahoma, sans-serif, serif; line-height: 25px; background-color: rgb(250, 250, 250);"><span style="font-size:12px;">其中"H:"是表示这是水平方向上的约束,"|"是表示superView,"-"表示一个间隔空间,这个间隔如果是和superView之间的,那么就是20px,如果是两个同级别的view,比如@"[label]-[label1]",那么这里表示的是8px.</span></span>
<span style="color:#ff0000;">@"V:|-100-[fl(==30)]"</span><span style="font-family: 'Helvetica Neue', Helvetica, STheiti, 微软雅黑, 黑体, Arial, Tahoma, sans-serif, serif; line-height: 25px;"><span style="font-size:12px;"><span style="color:#252525;"><span style="background-color: rgb(250, 250, 250);">其中"V:"中代表这是垂直方向上的约束,"|-100-"这里的意思就是距离头部为100px,相当于y坐标为100。后面的"[fl</span></span></span></span><span style="color: rgb(37, 37, 37); line-height: 25px; font-family: 'Helvetica Neue', Helvetica, STheiti, 微软雅黑, 黑体, Arial, Tahoma, sans-serif, serif; background-color: rgb(250, 250, 250);">(==30)]",是指定这个label的高度为30px.y坐标固定了,高度固定了,那这个view的约束就完成了。如果你有需要,你的高度值(或者其他同类型的)可以使用>=,==,<=来表示,甚至你可以组合来用,像上面的30</span>

运行结果对比:



2.LoginView中有2个控件,也可以由多个控件,上代码:

// 布局视图- (void)addSubviews{    // 设置背景颜色    self.backgroundColor = [UIColor cyanColor];        // 添加firstLabel    self.firstLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 200, 30)];    self.firstLabel.layer.borderWidth = 1;    self.firstLabel.layer.borderColor = [[UIColor lightGrayColor] CGColor];    self.firstLabel.layer.cornerRadius = 5;    self.firstLabel.text = @"点我";    self.firstLabel.textAlignment = NSTextAlignmentCenter;        [self addSubview:self.firstLabel];    [self.firstLabel release];        // 添加secLabel    self.secLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 150, 200, 30)];    self.secLabel.layer.borderWidth = 1;    self.secLabel.layer.borderColor = [[UIColor lightGrayColor] CGColor];    self.secLabel.layer.cornerRadius = 5;        self.secLabel.text = @"使劲点";    self.secLabel.textAlignment = NSTextAlignmentCenter;    [self addSubview:self.secLabel ];    [self.secLabel  release];            }#pragma mark - 屏幕旋转方法的实现- (void)layoutSubviews{    // 拿到两个控件    UILabel *fl = self.firstLabel;    UILabel *sl = self.secLabel;        fl.translatesAutoresizingMaskIntoConstraints = NO;// 这个必须写否则下面的约束方法不起作用    sl.translatesAutoresizingMaskIntoConstraints = NO;        // metrics参数 和 views参数    NSDictionary *metrics = @{@"Height":@30 , @"Width":@200};    NSDictionary *views = NSDictionaryOfVariableBindings(fl,sl);        //firstLabel控件约束    // 水平方向上的约束    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[fl]-50-|" options:0 metrics:metrics views:views]];    //垂直方向上的约束    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:<span style="color:#ff6666;">@"V:|-100-[fl(==Height)]"</span> options:0 metrics:metrics views:views]];            // secLabel约束    // 水平约束    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:<span style="color:#ff6666;">@"H:|-50-[sl(==fl)]"</span> options:0 metrics:metrics views:views]];    // 垂直约束    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:<span style="color:#ff6666;">@"V:[fl]-30-[sl(==fl)]"</span> options:0 metrics:metrics views:views]];    }

当两个控件时,我们可以像添加第一个控件时把第二个控件添加上去;同时也可以把第一个控件作为参照添加第二个控件,上面的方法就是把第一个控件作为参照,对控件重新布局;

首先看一下这个俩个参数:

// metrics参数 和 views参数    NSDictionary *metrics = @{@"Height":@30 , @"Width":@200};    <span style="color:#ff6666;">NSDictionary *views = NSDictionaryOfVariableBindings(fl,sl);</span>
metrics中的参数在VFL中有用到,就是format

views主要用在多控件的时候

通过下面的水平和垂直设置实现:第二个控件和第一个控件等高同宽(如下);也可以自己定义宽度和高度

@"H:|-50-[sl(==fl)]"

@"V:[fl]-30-[sl(==fl)]"


运行结果对比:

   

(竖屏)


    

(横屏)




0 0
原创粉丝点击