zoukankan      html  css  js  c++  java
  • iOS的自动布局

    iOS的自动布局

    一、StoryBoard和Xib的简介

    在这之前先简略介绍一下Xib/nib和StoryBoard。
    Xib/nib其实可以认为是一样的,nib是iOS3.0前的产物,它的本质是一个装着可执行二进制文件的文件夹。Xib的本质则是一个xml类型的描述文件,可以实现可视化的编程。两者在在UIViewController的生命周期方法loadView方法前都会转换成可执行的nib文件。
                  StoryBoard是多个Xib的集合的描述,也是xml格式的。
                  Storyboard和Xib的区别在于,一个工程中可以有多个Xib,一个Xib对应着一个控制器和多个视图;一个工程中只需要有一个StoryBoard就行,在包含多个控制器的时候选择使用storyBoard较好,而且StoryBoard可以清晰地描述界面之间的导航关系。
     

    二、纯代码、StoryBoard和Xib编码的优劣势分析

                  UI处理大致分为纯代码、StoryBoard和Xib三种方式,那么我们就在这里对比一下三种方式的优劣势。
    l  纯代码
    纯代码越来越受coder们的推崇,纯代码实现UI具有最好的代码重用性,也利用版本管理、代码追踪和代码的合并,大型项目大规模的使用。
    但是纯代码实现存在的问题是开发周期长,代码的维护复杂以及自动布局AutoLayout困难
    l  StoryBoard (iOS5.0之后推出的)
    StoryBoard实现的优点主要凸显在开发周期短,代码量少,可以明确看到每个ViewController的布局样式和各个控制器之间的跳转关系。
                  当然它的弊端也显而易见,不合适多人协作开发,ViewController的重用和自定义view的实现
    l  Xib
    Xib的优势在于开发周期快而且版本的维护和纯代码差异性不大,易于维护。
                  它的劣势往往体现在Xib的设置往往不是最终的设置,终究会被纯代码所替代。Xib的使用注意点:尽量将xib的工作和代码的工作隔离开来:能够使用xib完成的内容就统一使用xib来做,例如:三个Label其中两个在xib设置了字体而另一个却在代码中完成。尽量仅保持必要的、较少的IBOutlet和IBAction会是一个好方法。
     

    三、三种纯代码设置约束的自动布局

    自动布局经过的三个时期
    MagicNumber -> autoresizingMask -> autolayout
     
    在iphone1-iphone3gs时代 window的size固定为(320,480) 我们只需要简单计算一下相对位置就好了
    在iphone4-iphone4s时代苹果推出了retina屏 但是window的size不变
    在iphone5-iphone5s时代 window的size变了(320,568) 这时autoresizingMask 
    autoLayout自动布局是iOS6.0之后推出的,在6.0之前多使用autoresizingMasks属性,这个枚举类型的属性都是flexible(伸缩),在有了autoLayout之后这个就很少用了,可以不做了解。
    StoryBoard和Xib设置约束在这里也不做具体的介绍,主要介绍三种手写代码设置约束的方法。
    1、使用系统的NSLayoutConstraint实现
    obj1.property1 =(obj2.property2 * multiplier)+ constant value
     multiplier和constant 就是向量系数和偏移量
    1) 一个一个设置约束
    -(void)addConstraint:(NSLayoutConstraint *)constraint;
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:30]];
    2) 一组一组设置约束
     - (void)addConstraints:(NSArray *)constraints;
    [self.view addConstraints:@[
                                    //上
                                    [NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:30],
                                    //左
                                    [NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:10],
                                    //下
                                    [NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-170],
                                    //宽
                                    [NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.45 constant:0]]];
    2) Visual Format Language,翻译过来是“可视化格式语言”  是苹果公司为了简化Autolayout的编码而推出的抽象语言  相当于打出象形文字似得,而且要全在字符串里写,遇到错误比较难调,但是相对来说代码精简了不少.
    VFL的详细语法 可以在官方文档中 搜“Visual Format” 就能搜到
     上面的方法中传到的两个参数metrics 和 views 是两个字典。
    第一个字典metrics是用来告诉系统里面的每一个值对应哪个字母
    第二个字典views是 用来告诉里面的每一个控件对应字符串里的什么
    如果整个VFL语言里的所有控件你都是用原名写在里面的,那可以用宏代替
     注释:
     
     |: 表示父视图
     -:表示距离
     V:  :表示垂直
     H:  :表示水平
     >= :表示视图间距、宽度和高度必须大于或等于某个值
     <= :表示视图间距、宽度和高度必须小宇或等于某个值
     == :表示视图间距、宽度或者高度必须等于某个值
     @  :>=、<=、==  限制   最大为  1000
     
     
     1.|-[view]-|:  视图处在父视图的左右边缘内
     2.|-[view]  :   视图处在父视图的左边缘
     3.|[view]   :   视图和父视图左边对齐
     4.-[view]-  :  设置视图的宽度高度
     5.|-30.0-[view]-30.0-|:  表示离父视图 左右间距  30
     6.[view(200.0)] : 表示视图宽度为 200.0
     7.|-[view(view1)]-[view1]-| :表示视图宽度一样,并且在父视图左右边缘内
     8. V:|-[view(50.0)] : 视图高度为  50
     9: V:|-(==padding)-[imageView]->=0-[button]-(==padding)-| : 表示离父视图的距离
    这两个视图间距必须大于或等于0并且距离底部父视图为padding。
     10:  [wideView(>=60@700)]  :视图的宽度为至少为60 不能超过  700
     11: 如果没有声明方向默认为  水平  H:
     
    - (void)setConstraintsByVFL {
        NSDictionary *views = NSDictionaryOfVariableBindings(self.view,_testView1,_testView2,_testView3);
       
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[_testView1(==_testView2)]-10-[_testView2]-10-|" options:0 metrics:0 views:views]];
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[_testView1(<=700)]-10-[_testView3]-10-|" options:0 metrics:0 views:views]];
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[_testView2(<=700)]-10-[_testView3]-10-|" options:0 metrics:0 views:views]];
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_testView3]-10-|" options:0 metrics:0 views:views]];
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_testView3(==150)]-10-|" options:0 metrics:0 views:views]];
       
    }
     

    2.Masonry的使用

    mas_makeConstraints 是给view添加约束,约束有几种,分别是边距,宽,高,左上右下距离,基准线。添加过约束后可以有修正,修正有offset(位移)修正和multipliedBy(倍率)修正。
    语法一般是 make.equalTo or make.greaterThanOrEqualTo or make.lessThanOrEqualTo + 倍数和位移修正。
     
    注意点1: 使用 mas_makeConstraints方法的元素必须事先添加到父元素的中,例如[self.view addSubview:view];
     
    注意点2: masequalTo 和 equalTo 区别:masequalTo 比equalTo多了类型转换操作,一般来说,大多数时候两个方法都是 通用的,但是对于数值元素使用mas_equalTo。对于对象或是多个属性的处理,使用equalTo。特别是多个属性时,必须使用equalTo,例如 make.left.and.right.equalTo(self.view);
     
    注意点3: 注意到方法with和and,这连个方法其实没有做任何操作,方法只是返回对象本身,这这个方法的左右完全是为了方法写的时候的可读性 。make.left.and.right.equalTo(self.view);和make.left.right.equalTo(self.view);是完全一样的,但是明显的加了and方法的语句可读性更好点。
    // exp1: 中心点与self.view相同,宽度为400*400
    -(void)exp1{
        UIView *view = [UIView new];
        [view setBackgroundColor:[UIColor redColor]];
        [self.view addSubview:view];
        [view mas_makeConstraints:^(MASConstraintMaker *make) {
             make.center.equalTo(self.view);
             make.size.mas_equalTo(CGSizeMake(400,400));
        }];
    }
    //exp2: 上下左右边距都为10
    -(void)exp2{
        UIView *view = [UIView new];
        [view setBackgroundColor:[UIColor redColor]];
        [self.view addSubview:view];
        [view mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
            //  make.left.equalTo(self.view).with.offset(10);
            //  make.right.equalTo(self.view).with.offset(-10);
            //  make.top.equalTo(self.view).with.offset(10);
            //  make.bottom.equalTo(self.view).with.offset(-10);
        }];
    }
    //exp3 让两个高度为150的view垂直居中且等宽且等间隔排列 间隔为10
    -(void)exp3{
        UIView *view1 = [UIView new];
        [view1 setBackgroundColor:[UIColor redColor]];
        [self.view addSubview:view1];
        UIView *view2 = [UIView new];
        [view2 setBackgroundColor:[UIColor redColor]];
        [self.view addSubview:view2];
        [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.mas_equalTo(self.view.mas_centerY);
            make.height.mas_equalTo(150);
            make.width.mas_equalTo(view2.mas_width);
            make.left.mas_equalTo(self.view.mas_left).with.offset(10);
            make.right.mas_equalTo(view2.mas_left).offset(-10);
        }];
        [view2 mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.mas_equalTo(self.view.mas_centerY);
            make.height.mas_equalTo(150);
            make.width.mas_equalTo(view1.mas_width);
            make.left.mas_equalTo(view1.mas_right).with.offset(10);
            make.right.equalTo(self.view.mas_right).offset(-10);
        }];
    }
     
     
     
  • 相关阅读:
    Azure 存储简介
    Databricks 第6篇:Spark SQL 维护数据库和表
    Databricks 第5篇:Databricks文件系统(DBFS)
    Databricks 第4篇:pyspark.sql 分组统计和窗口
    IDEA分析JAVA内存溢出和内存泄漏
    Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Connection is broken: "session closed" [90067-200] 解决
    Java 中初始化 List 集合的 8 种方式!
    java list算法问题(给定一 int 数组返回倒序的最大连续递增的区间(至少大于等于2)数组倒序)
    uni-app知识点:页面滚动到指定位置(即锚点实现)、设置背景颜色backgroundColor无效的问题、导航栏设置角标及动态控制修改角标数字
    @Transactional注解为什么不生效
  • 原文地址:https://www.cnblogs.com/bao-yu/p/5411038.html
Copyright © 2011-2022 走看看