• ios 布局


    Layout

    1. 什么是布局

    是指在一个视图中,如何摆放它的子视图 (设置子视图的位置和大小)

    2. 可能导致屏幕尺寸大小发生变化的原因**

    ** a.** 屏幕方向 (横竖屏)
    ** b.** 设备不同 (3.5寸, 4寸, 4.7寸, 5.5寸)
    ** c.** 状态栏 隐藏

    特殊的状态栏:
    来电时 绿色的状态栏
    开启个人热点 蓝色的状态栏
    录音时 红色的状态栏

    ** d.** 各种bar
    NaviationBar : 竖屏时 64点高 横屏时 52个点高
    ToolBar : 44 / 32 个点
    TabBar : 49 个点

    ** e.** 键盘弹起和收回

    3. 如何布局?
    方法一: 纯代码布局 ** ( 古老的方法: ** -(void)viewDidLayoutSubviews;)**

    理念:当屏幕发生变化时,自动执行一段代码,在代码中根据新的屏幕大小重新计算各个视图的frame,从而达到重新定位的目的

    特点:功能强大,非常繁琐

    //纯代码布局  :
    -(void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];
        //纯代码布局
        CGFloat viewWidth = (self.view.bounds.size.width - 50) / 2;
        CGRect frame = self.myView1.frame;
        frame.origin.x = 20;
        frame.origin.y = 20;
        frame.size.width = viewWidth;
        frame.size.height = 40;
        self.myView1.frame = frame;
        
        frame.origin.x += 10 + viewWidth;
        self.myView2.frame = frame;
    }
    

    **作业要求 **
    给UIView添加分类,实现效果
    可以让view的子类做成圆的或圆角矩形
    两个方法

    一个方法 调用 直接做成圆形 (如果调用该方法的view宽高不一样,需要程序在该方法处崩掉 《断言》)
    一个方法 调用 通过传入的圆角半径,做成圆角矩形


    方法二: Auto Resizing 以前的一种自动布局技术(Auto Resizing布局)**

    理念:根据屏幕的等比变化,同样等比调整视图的距离上下左右边缘的距离,或等比调整视图的大小
    特点:简单易用

    //Auto Resizing布局:	
    - (void)viewDidLoad {
        [super viewDidLoad];
        UIView *myView = [[UIView alloc]init];
        myView.frame = CGRectMake(self.view.frame.size.width - 20 - 100, 20, 100, 40);
        myView.backgroundColor = [UIColor redColor];
        //手动设置 AutoResizing  这里和故事版中点亮红线的方向是反
        myView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
        [self.view addSubview:myView];
    }
    

    方法三:Auto Layout 最新的自动布局方法**

    ** 理念:**将视图所在的位置使用多个约束条件描述出来,当屏幕大小发生变化时,系统会自动根据设定的多个约束,由系统计算出 不违背所有条件的一个合适的frame

    ** 工作原理**
    通过一系列的“约束constraint”来描述视图的展示位置

    什么是约束?
    代表一个条,只需要设定一些约束,则系统会根据这一堆约束,自动计算出符合约束的frame

    如何创建约束?
    方式一:用代码创建
    方式二:在故事版中可视化配置

    约束的两个原则
    1.描述清楚 (x, y, w, h 全部通过约束描述出来)
    2.互不冲突

    使用代码创建AutoLayout约束
    如何实现:
    step1:创建约束对象 NSLayoutConstraint
    step2:将约束对象加入到视图的父试图中

    ** 创建一个约束对象**
    方式一 : 万能公式法

    view1.attr view2.attr *multiplier + constant
    文字描述:按键1距离视图的左边为20个点
    公式描述:button1.left = self.view.left * 1 + 20
    文字描述:按键1的宽度是按键2宽度的一半
    公式描述:button1.width = button2.width * 0.5 + 0
    文字描述:按键1的右边和按键2的左边间隔10
    公式描述:button1.right = button2.left * 1 + 10

    方法二: VFL 法 (Visual Format Language)

    是什么?
    一个字符串,具有一定的格式,不同的格式代表不同的约束,并且,一个字符串往往能一次性表达出多个约束

    如何写VFL字符串?
    文字:button1和button2之间的间距为30
    VFL:[button1]-30-[button]
    文字:button1的宽度为50
    VFL:[button1(==50)] 或 [button1(50)]
    文字:button1 距离 左边20,button2距离右边20, button1和button2间隔10, button1宽度和button2的宽度相等
    VFL: |-20-[button1(button2)]-10-[button2(button1)]-20-|
    文字:button1 距离顶部 为20
    VFL: V:|-20-[button1]
    文字:button1 和 button2 垂直方向间隔10
    VFL: V:[button1]-10-[button2]

    		>**VFL 特殊符号的含义**
    			|      代表父视图的边缘
    			H:|  代表父试图的左边缘
    			V:|  代表父试图的上边缘
    			[]   代表一个子视图
    			()   代表一个宽度或高度的条件
    			-x-   代表间距是 x
    			-     代表标准间距 8 
    

    方法三:
    三方框架:Masonry

    方式一:用代码创建

    //万能公式法;
    - (void)viewDidLoad {
        [super viewDidLoad];
        UIView *myView1 = [[UIView alloc]init];
        myView1.backgroundColor = [UIColor redColor];
        UIView *myView2 = [[UIView alloc]init];
        myView2.backgroundColor = [UIColor greenColor];
        [self.view addSubview:myView1];
        [self.view addSubview:myView2];
        
        //关闭系统 Autoresizing
        myView1.translatesAutoresizingMaskIntoConstraints = NO;
        myView2.translatesAutoresizingMaskIntoConstraints = NO;
        
        /**创建左边view的约束对象**/
        //左边距离屏幕左边 20
        NSLayoutConstraint *c1 = [NSLayoutConstraint constraintWithItem:myView1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:20];
        //上边距离屏幕顶部 20
        NSLayoutConstraint *c2 = [NSLayoutConstraint constraintWithItem:myView1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:20];
        //myView1的宽度 等于 myView2的宽度
        NSLayoutConstraint *c3 = [NSLayoutConstraint constraintWithItem:myView1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:myView2 attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
        //高度为 40
        NSLayoutConstraint *c4 = [NSLayoutConstraint constraintWithItem:myView1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40];
        
        //约束对象添加到父试图上
        [self.view addConstraint:c1];
        [self.view addConstraint:c2];
        [self.view addConstraint:c3];
        [self.view addConstraint:c4];
        
        
        /**myView2 约束**/
        //顶部
         NSLayoutConstraint *c5 = [NSLayoutConstraint constraintWithItem:myView2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view    attribute:NSLayoutAttributeTop multiplier:1 constant:20];
        //高度
          NSLayoutConstraint *c6 = [NSLayoutConstraint constraintWithItem:myView2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil    attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40];
        //右边
        NSLayoutConstraint *c7 = [NSLayoutConstraint constraintWithItem:myView2 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view    attribute:NSLayoutAttributeRight multiplier:1 constant:-20];
        //左边
        NSLayoutConstraint *c8 = [NSLayoutConstraint constraintWithItem:myView2 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:myView1    attribute:NSLayoutAttributeRight multiplier:1 constant:10];
        
        //约束对象添加到父试图上
        [self.view addConstraint:c5];
        [self.view addConstraint:c6];
        [self.view addConstraint:c7];
        [self.view addConstraint:c8];
    }
    

    //VEL法:

    - (void)viewDidLoad {
        [super viewDidLoad];
        UIView *view1 = [[UIView alloc]init];
        view1.backgroundColor = [UIColor redColor];
        UIView *view2 = [[UIView alloc]init];
        view2.backgroundColor = [UIColor greenColor];
        [self.view addSubview:view1];
        [self.view addSubview:view2];
        
        //关闭 autoresizing 自动翻译约束的 功能
        view1.translatesAutoresizingMaskIntoConstraints = NO;
        view2.translatesAutoresizingMaskIntoConstraints = NO;
        
        //VFL表达式
        //1.准备一个 VFL
        NSString *hVFL = @"H:|-left-[view1]-space-[view2(view1)]-right-|";
        //创建垂直方向约束
        NSString *vVFL = @"V:|-top-[view1(40)]";
        
        //创建一个对照表
        NSDictionary *metricsDic = @{
                        @"left":@20,
                        @"right":@20,
                        @"space":@10,
                        @"top":@20};
     
        //该宏会创建 一个字典, 该字典的value就是传入的对象, 该字典会自动使用传入的对象的名称 作为key
        NSDictionary *dic = NSDictionaryOfVariableBindings(view1,view2);
        
        NSArray<NSLayoutConstraint*> *constraints = [NSLayoutConstraint constraintsWithVisualFormat:hVFL options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metricsDic views:dic];
        
        NSArray<NSLayoutConstraint*> *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vVFL options:NSLayoutFormatAlignAllTop metrics:metricsDic views:dic];
        
        
    //    NSArray<NSLayoutConstraint*> *constraints = [NSLayoutConstraint constraintsWithVisualFormat:hVFL options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:nil views:@{@"view1":view1, @"view2":view2}];
    //    NSArray<NSLayoutConstraint*> *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vVFL options:NSLayoutFormatAlignAllTop metrics:nil views:@{@"view1":view1}];
        
        [self.view addConstraints:constraints];
        [self.view addConstraints:constraints2];
        }
    
    

    方式二:在故事版中可视化配置

    ```

    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    //定时器
    @property(nonatomic,strong) CADisplayLink *link;
    @end
    @implementation ViewController
    //懒加载
    -(CADisplayLink *)link {
    if (!_link) {
    //每刷新一次 调用一次 定时器的事件方法
    _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(rotation:)];
    //手动将定时器 加入到 事件循环队列中
    [_link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    _link.paused = YES;
    }
    return _link;
    }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.link.paused = !self.link.paused;
    }

    -(void)rotation:(CADisplayLink*)sender {
        // 5秒钟 转一圈
    //    360 / 5; 求出1秒钟多少度  72
    //    1秒钟调用 60次  转72度
    //    每次调用 转  72/60.0
        //不能用角度 因为参数 需要的是 弧度
        self.imageView.layer.transform =  CATransform3DRotate(self.imageView.layer.transform, angleToRadian(72/60.0), 1, 1, 1);
    }  - (void)viewDidLoad {
        [super viewDidLoad]; 
        self.imageView.layer.cornerRadius = self.imageView.bounds.size.width * 0.5;
        self.imageView.layer.borderWidth = 3;
        self.imageView.layer.borderColor = [UIColor redColor].CGColor;
        self.imageView.layer.masksToBounds = YES;
        self.imageView.layer.anchorPoint = CGPointMake(0.2, 0.2);
        for (NSInteger i = 0; i < 8; i++) {
            CALayer *layer = [CALayer layer];
            //为层添加图片内容
            layer.contents = (id)[UIImage imageNamed:@"60"].CGImage;
            layer.bounds = CGRectMake(0, 0, 20, self.imageView.bounds.size.height * 0.5);
            layer.position = CGPointMake(self.imageView.bounds.size.width * 0.5, self.imageView.bounds.size.height * 0.5);
            layer.anchorPoint = CGPointMake(0.5, 1);
            layer.transform = CATransform3DMakeRotation(M_PI_4 * i, 0, 0, 1);
            [self.imageView.layer addSublayer:layer];
        }
    }
    

    方法三:
    三方框架:Masonry

    导入头文件:#import "Masonry.h"
    - (void)viewDidLoad {
        [super viewDidLoad];
        UIView *myView = [[UIView alloc]init];
        myView.backgroundColor = [UIColor redColor];
        [self.view addSubview:myView];
        
        [myView mas_makeConstraints:^(MASConstraintMaker *make) {
    //        equalTo  后面接的是 引用类型
    //        mas_equalTo  后面接的是直类型
            make.size.mas_equalTo(CGSizeMake(200, 100));
            make.center.equalTo(self.view);
        }];  
        UIView *myView2 = [[UIView alloc]init];
        myView2.backgroundColor = [UIColor greenColor];
        [self.view addSubview:myView2];
        [myView2 mas_makeConstraints:^(MASConstraintMaker *make) {
    //        make.top.equalTo(self.view);
    //        make.left.equalTo(self.view);
    //        make.right.equalTo(self.view);
            make.top.and.left.and.right.equalTo(self.view);
            make.size.height.mas_equalTo(40);
        }];
    }
    

    //——————————————————————————————————

     - (void)viewDidLoad {
        [super viewDidLoad];
        //创建文字类型的图层
        CATextLayer *tLayer = [CATextLayer layer];
        tLayer.string = @"这是一个文字";
        tLayer.fontSize = 20;
        tLayer.foregroundColor = [UIColor whiteColor].CGColor;
        tLayer.backgroundColor = [UIColor blackColor].CGColor;
        
        tLayer.bounds = CGRectMake(0, 0, 200, 40);
        tLayer.position = CGPointMake(100, 100);
        tLayer.anchorPoint = CGPointZero;
        
        //将文字层 添加到 self.view.layer 上
        [self.view.layer addSublayer:tLayer];
        
        
        //图形类型的图层
        CAShapeLayer *sLayer = [CAShapeLayer layer];
        self.sLayer = sLayer;
        sLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(10, 10, 100, 50) cornerRadius:10].CGPath;
        sLayer.strokeColor = [UIColor redColor].CGColor;
        sLayer.fillColor = [UIColor whiteColor].CGColor;
        
        sLayer.backgroundColor = [UIColor blackColor].CGColor;
        
        sLayer.bounds = CGRectMake(0, 0, 200, 200);
        sLayer.position = CGPointMake(50, 250);
        sLayer.anchorPoint = CGPointZero;
        
        //添加边框
        sLayer.borderColor = [UIColor blueColor].CGColor;
        sLayer.borderWidth = 5;
        sLayer.cornerRadius = 10;
        
        //将图形层 添加到 self.view.Layer 上
        [self.view.layer addSublayer:sLayer];
        
    }
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //    arc4random_uniform 取出 0 ~ x-1
        self.sLayer.borderWidth = arc4random_uniform(25);
        self.sLayer.cornerRadius = arc4random_uniform(30);
    
    }
    
    //该方法在view加载完会调用一次, 在屏幕发生旋转也会自动调用
    -(void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];
        CGFloat space20 = 20;
        CGFloat space10 = 10;
        CGFloat viewWidth = (self.view.bounds.size.width - space20 * 2 - space10) * 0.5;
        CGFloat viewHeight = 40;
        CGFloat viewX = space20;
        CGFloat viewY = space20;
        
        CGFloat greenViewWidth = 20;
        CGFloat greenViewHeight = 20;
        
        CGRect frame = CGRectMake(viewX, viewY, viewWidth, viewHeight);
        self.myView1.frame = frame;
        
        //设置 第二个view的frame
        frame.origin.x += viewWidth + space10;
        self.myView2.frame = frame;
        
        //设置imageview的frame
        frame.origin.x = space20;
        frame.origin.y += viewHeight + space10;
        frame.size.width = self.view.bounds.size.width - space20 * 2;
        frame.size.height = self.view.bounds.size.height - space20 * 2 - space10 * 2 - greenViewHeight - viewHeight;
        self.imageView.frame = frame;
        
        //设置小绿view1的frame
        frame.origin.x = self.view.bounds.size.width - (space20 + greenViewWidth);
        frame.origin.y = self.view.bounds.size.height - space20 - greenViewHeight;
        frame.size.width = greenViewWidth;
        frame.size.height = greenViewHeight;
        self.greenView1.frame = frame;
        //设置小绿view2的frame
        frame.origin.x -= greenViewWidth + space10;
        self.greenView2.frame = frame;
        //设置小绿view3的frame
        frame.origin.x -= greenViewWidth + space10;
        self.greenView3.frame = frame;
    }
    
    成功的三大原则: 1、坚持 2、不要脸 3、坚持不要脸
  • 相关阅读:
    php实现题目抢答、商品秒杀等类型的需求
    php实现批量修改文件名称
    php微信支付问题之 cURL error 60: SSL certificate: unable to get local issuer certificate
    laravel5.2之logout注销账号无效
    分布式版本控制git常见问题之gitignore冲突(精简版)
    laravel实现多数据库连接配置
    laravel实现excel表格导出
    js实现超出一定字数隐藏并用省略号"..."代替,点击后又可进行展开和收起,
    你会python不?当你听到这个问题要谨慎回答!!!
    DirectX 入门1-初识DirectX Tool Kit
  • 原文地址:https://www.cnblogs.com/xulinmei/p/7420176.html
Copyright © 2020-2023  润新知