美文网首页
代码布局

代码布局

作者: tsiic | 来源:发表于2018-02-05 15:31 被阅读0次

    xib 不是全能的,有的时候不能使用 xib 进行 UI 布局的时候,还是得使用代码布局。

    代码布局有两个点要注意:

    1. 布局计算

    如果是计算frame等,那么要注意这个计算 只进行一次,因此在viewDidLoad做的计算不一定是正确的值,即使是正确的值,也无济于事,因为计算一次这一点意味着计算 frame 无法适配屏幕旋转的情形。
    更稳妥的frame计算是放在viewDidLayoutSubviews等方法里,这是会调用多次的方法,每当UI变更的时候就可以在这里更新计算值,eg:

        override func viewDidLayoutSubviews() {
            spin.center = CGPoint(x: loginButton.bounds.width / 2, y: loginButton.bounds.height / 2)
        }
    

    2. 使用Constraints

    更有效的方法当然是使用约束布局法。
    这就必须提到一个提高约束编写效率的库 Masonry,这个库已经适配了iPhone X,可以说节省了非常多的编码时间。
    在实际使用的时候有两个非常有用的方法:

    - (void)didMoveToSuperview

    调用两次,一次是视图被添加到父视图的时候,第二次则是视图被移出父视图的时候,因此我们可以在这里添加一些相对父视图的约束,eg:

    - (void)didMoveToSuperview {
        [super didMoveToSuperview];
        // Add constraints to super view
        if (self.superview) {
            [self mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.equalTo(self.superview.mas_left);
                make.top.equalTo(self.superview.mas_top);
                make.width.mas_equalTo(self.superview.bounds.size.width);
                make.height.equalTo(@36);
            }];
        }
    }
    

    一定要记住虽然名字是 MoveToSuperview,但是移除的时候也会调用,这时候 self.superview 已经为nil,所以要做 if 判定,不然会crash。
    这里宽度我用的是计算宽度,因为父视图是scrollView,不指定宽度的话scrollView会被撑大,所以不能直接设定右侧约束,我就因为这个坑踩了很久才出来。

    - (void)layoutSubviews

    我一开始以为用了上面的方法就万事大吉了,但是却不够。因为我在上面的方法里用了superView的bounds。
    和前文提到的一样,虽然是用的约束,但是这个对于屏幕宽度的计算依然是一次性的,在屏幕旋转的时候虽然约束会更新视图,但是width被我们钉死了。所以需要在更新视图的时候更新约束去获取最新的宽度信息:

    - (void)layoutSubviews {
        [super layoutSubviews];
        [self mas_updateConstraints:^(MASConstraintMaker *make) {
            make.width.mas_equalTo(self.superview.bounds.size.width);
        }];
    }
    

    相关文章

      网友评论

          本文标题:代码布局

          本文链接:https://www.haomeiwen.com/subject/virjgxtx.html