• 15-UIKit(view布局、Autoresizing)


    目录:

    1. 纯代码布局

    2. 在View中进行代码布局

    3. Autoresizing

    回到顶部

    1. 纯代码布局

         纯代码布局分VC下和V下

         [MX1-layout-code]

         在VC下覆盖viewDidLayoutSubviews方法,在方法中写布局,一般会把要布局的控件拉成属性

         当界面大小发生改变时(竖屏变横屏, 出现工具栏或各种bar....), 调用此方法。注意这个方法在运行之后就会调用,只是在界面发生变化后会再次调用,最终的布局在这里起作用。

         此方法的调用在Storyboard布局后。

         注意关掉AutoLayout

         1.1 计算坐标

         1> 两个按钮等宽

         2> ImageView:

               上下左右永远保持70, 50, 20, 20

         3>三个小按钮(20x20), 永远保持在右下角:

    // 当界面大小发生改变时(竖屏变横屏, 出现工具栏或各种bar....), 调用此方法。注意这个方法在运行之后就会调用,只是在界面发生变化后会再次调用。
    
    -(void)viewDidLayoutSubviews{
    
        [super viewDidLayoutSubviews];
    
        // NSLog(@"11111");
    
        CGRect frame = self.button1.frame;
    
        CGFloat buttonWidth = (self.view.bounds.size.width - 20 * 2 - 10) / 2;
    
        frame.size.width = buttonWidth;
    
        self.button1.frame = frame;
    
        frame.origin.x += buttonWidth + 10;
    
        self.button2.frame = frame;
    
       
    
        frame = CGRectZero;
    
        frame.origin = CGPointMake(20, 70);
    
        frame.size = CGSizeMake(self.view.bounds.size.width - 20 - 20, self.view.bounds.size.height - 70 - 50);
    
        self.imageView.frame = frame;
    
       
    
        frame.size = CGSizeMake(20, 20);
    
        frame.origin.x = self.view.bounds.size.width - 20 - 10 - 10  - 20 * 3;
    
        frame.origin.y = self.view.bounds.size.height - 20 - 20;
    
        self.btn1.frame = frame;
    
        frame.origin.x = self.view.bounds.size.width - 20 - 10 - 20 * 2;
    
        self.btn2.frame = frame;
    
        frame.origin.x = self.view.bounds.size.width - 20 - 20;
    
        self.btn3.frame = frame;
    
        NSLog(@"调用了viewDidLayoutSubviews方法");
    
    }

         1.2 各种Bar的影响

         [MX2-Bar-Code]

               从iOS7开始,任何一个VC类都拥有两个属性:

                    .topLayoutGuide

                    .bottomLayoutGuide

               这两属性保存了VC上面和下面各种Bar所占用的空间。

               这两属性都是遵守了UILayoutSupport协议的对象,此协议规定了一个属性:length, 用来表示Bar所占的空间。

               一般的,这两属性用于VC渗透到上下各种Bar下面的情况下,计算Bar所占用的空间

               可以在Xcode中设置VC不渗透到Bar下面去(在第四个检查器勾掉under bottom bars)。此时.topLayoutGuide和.bottomLayoutGuider的length都为0.

               所以,不管VC是否渗透到Bar的下面,坐标上都加入这两属性是没错的。

               补充:

                    可以设置VC属性:

                          .edgesForExtendedLayout = ….

                    来设置VC是否渗透到Bar下面

    -(void)viewDidLayoutSubviews{
    
        [super viewDidLayoutSubviews];
    
        // 上下都不渗透延伸
    
        self.edgesForExtendedLayout = UIRectEdgeNone;
    
        CGRect frame = self.button.frame;
    
        frame.origin.x = self.view.bounds.size.width - 20 - frame.size.width;
    
        frame.origin.y = 20;// 因为在该视图的第三个检查器设置关掉了使用top bars
    
        self.button.frame = frame;
    
    }

    1.3 自己绘制的图形

               当界面大小发生变化,自动绘制的图形也会有布局问题。

               [MX3-Redraw]

               view视图有一个属性:contentMode,这个属性决定着当view的大小改变时,做出什么反应。

               默认是Scale To Fill   左右上下全拉伸

               如果ImageView  一般会选择Aspect Fit /Aspect Fill 

               如果是自定义的绘制图形,应该设置成Redraw, 这样,当view大小发生改变时,会重绘图形。

    // 设置该view的mode为Redraw,那么当界面发生变化时会重新调用这个进行重绘
    
    - (void)drawRect:(CGRect)rect
    
    {
    
        // Drawing code
    
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextSaveGState(context);
    
        UIBezierPath *path = [UIBezierPath bezierPath];
    
        [path moveToPoint:CGPointMake(40, 40)];
    
        [path addLineToPoint:CGPointMake(120, 40)];
    
        [path addLineToPoint:CGPointMake(40, 120)];
    
        [path closePath];
    
        [[UIColor redColor] setStroke];
    
        [path stroke];
    
        CGContextRestoreGState(context);
    
    }

    回到顶部

    2. 在View中进行代码布局

               2.1 View类中有一个方法:layoutSubviews, 给view中所有子view布局。

                    当视图的大小改变时,以下三个方法会被自动依次调用

                          1>   VC: viewWillLayoutSubviews

                          2>   V:  layoutSubviews

                          3>   VC: viewDidLayoutSubviews

                    View:

                               drawRect:    绘制                    setNeedsDisplay

                               layoutSubviews:  布局           setNeedsLayout

         [MX4-ViewLayout]  自定义一个视图(Cell) 用代码进行布局

    // 当界面大小改变时或setNeedsLayout调用此方法,这是手动布局,注意关掉自动布局
    -(void)layoutSubviews{
        [super layoutSubviews];
        CGFloat x = self.downLoadedIcon.frame.origin.x;
        if (self.music.downloaded) {
            x += 20;
        }
        CGRect frame;
        if (self.music.highQuality) {
            frame = self.highQualityIcon.frame;
            frame.origin.x = x;
            self.highQualityIcon.frame = frame;
            x += 20;
        }
        frame = self.subLabel.frame;
        frame.origin.x = x;
        self.subLabel.frame = frame;
    }

    回到顶部

    3. Autoresizing

         3.1 什么是Autoresizing

               是老的布局技术,以前叫spring/struct布局

               操作简单, 功能有限,现在依然有效

               还可以和AutoLayout技术一起使用。

         3.2 工作原理

               根据父视图的变化,按父视图变化的比例改变子视图的大小,或者其他计算式来确定子视图的frame.

         3.3 怎么用

               [MX5-Autoresizing]

               外边四条红线约束子视图离边界的间距

               里边的两条线用来指示子视图是否可以随父视图的变化而伸缩

               [MX6-Autoresizing]

         3.4 和代码结合使用

               如果Autoresizing技术无法满足需求时,可以用代码补充

         3.5 用纯代码方式使用Autoresizing

               每个视图都有一个属性:autoresizingMask, 用来描述Autoresizing的设置

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
    }

    附:

    OC语言中的枚举定义常见用法:

         typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {

        UIViewAutoresizingNone                 = 0,  //0

        UIViewAutoresizingFlexibleLeftMargin   = 1 << 0, //1

        UIViewAutoresizingFlexibleWidth        = 1 << 1, //2

        UIViewAutoresizingFlexibleRightMargin  = 1 << 2, //4

        UIViewAutoresizingFlexibleTopMargin    = 1 << 3, //8

        UIViewAutoresizingFlexibleHeight       = 1 << 4, //16

        UIViewAutoresizingFlexibleBottomMargin = 1 << 5  //32

      };

     

       1 << 1  :

       0000 0001 << 1 : 0000 0010 (2)

       1 << 2  :

       0000 0001 << 2 : 0000 0100 (4)

         UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight

               0000 0010

               0000 0100

               0001 0000

            -------------

               0001 0110      6

    作业:

    1. 参考H01资源包, 实现播放界面,用代码布局

    2. 图片涂鸦

         参考PhotoDraw项目

     

  • 相关阅读:
    MySQL之架构与历史(二)
    MySQL之架构与历史(一)
    MySQL之体系结构与存储实例
    Redis实现之复制(二)
    Redis实现之复制(一)
    选项卡
    滑动效果
    选择器
    下拉列表
    1.__tostring()这个方法在类里可以直接输出对象。2.克隆对象的运用
  • 原文地址:https://www.cnblogs.com/yangmx/p/3532912.html
Copyright © 2020-2023  润新知