美文网首页IOSios自动布局
AutoLayout的那些事(二)

AutoLayout的那些事(二)

作者: MangoMade | 来源:发表于2016-03-30 22:26 被阅读629次

    Mango's Blog

    接上篇,本篇主要内容为:

    • AutoLayout与Frame篇
    • AutoLayout动画篇
    • AutoLayout比例设置

    AutoLayout与Frame篇

    在使用AutoLayout的时候你可能也会同时也会用到frame,比如需要用到layer的时候。

    那么你可能会遇到这种情况,想让layer的尺寸是由其它视图尺寸设定的,而这个视图又是由约束控制布局的。如果将layer的初始化与view的初始化放在一个方法中,类似于viewDidLoad的方法中

    layer.bounds = CGRectMake(0,0,view.bounds.size.widith * 0.5,50)
    

    那么很可能最终layer的宽度是0。

    这是因为约束被设置之后它并不会立即对view作出改变,而是要等到layout时,才会对视图的尺寸进行修改。而layout通常是在视图已经加载到父视上时。

    所以我们如果在viewDidLoad中设置了约束,要等到viewDidAppear时view的尺寸才会真正改变。

    那么,如果需要既用约束布局,又用frame布局,如果能让它们很好的协作呢?

    一个很好的解决办法是:吧frame设置写到layoutSubviews中或者写到viewDidLayoutSubviews中即可。因为约束生效时view的center或者bounds就会被修改,center或者bounds被修改时layoutSubview,就会被调用,随后viewDidLayoutSubviews就回被调用。这个时候,设置约束的视图frame就不再是(0,0,0,0)了

    如果我们必须要将约束和frame写在同一方法中,写完约束就设置frame,而不是想把frame的设置写到layoutSubview中(比如我们设置好约束后马上就想根据约束的结果计算高度),那么我们还可以在设置完约束之后手动调用layoutIfNeeded方法,让视图立即layout,更新frame。在这之后就可以拿到设置约束的视图的尺寸了。

    AutoLayout动画篇

    这篇的内容非常简单,就是介绍约束布局的视图如何进行位移动画。

    如果我们的一个视图是通过设置frame来布局的,那么我们在位移动画时直接改变frame就可以了。很简单。

    可是在约束布局的视图中,设置frame这个办法就无效了。那我们怎么办?

    网上有很多人的办法就是:拿到想要做动画的约束,在动画之前对约束进行修改,在动画的block中调用setNeedsLayout方法。

    这个方法我觉得非常的麻烦,为了方便地拿到约束,我们通常还需要把约束设置成属性,动画一多那岂不就是完蛋了?

    一种更好的方法就是设置视图的transform属性。

    比如我想要让视图做一个x轴+50的位移,

    self.view.transform = CGAffineTransformMakeTranslation(50, 0)
    

    这样设置即可。CGAffineTransformMakeTranslation这个方法就是设置位置。

    AutoLayout比例设置

    如果我们用autoLayout想把一个视图的中心设置到屏幕横向和纵向的1/4处:

    button.snp_makeConstraints{ make in
        make.centerX.equalTo(self.view).multipliedBy(0.25)
        make.centerY.equalTo(self.view).multipliedBy(0.25)
    }
    

    这就相当于

    button.center = CGPointMake(self.view.bounds.size.width * 0.25 ,self.view.bounds.size.height * 0.25)
    

    那么AutoLayout中的倍数,具体表示什么呢?

    let view = UIView()
    self.view.addSubview(view)
    var bottomConstraint : Constraint!
    view.snp_makeConstraints { (make) in
        make.height.equalTo(50)
        make.width.equalTo(50)
        make.centerX.equalTo(self.view.snp_centerX)
        bottomConstraint = make.bottom.equalTo(self.view.snp_centerY).constraint
    }
    self.view.layoutIfNeeded()
    print(view.frame)
    //打印结果 y:318 height:50 和为368
    bottomConstraint.uninstall()
    view.snp_makeConstraints { (make) in
        make.bottom.equalTo(self.view.snp_centerY).multipliedBy(1.5)
    }
    self.view.layoutIfNeeded()
    print(view.frame)
    //打印结果 y:318 height:50 和为552,刚好是368的1.5倍
    //所以我们可以得出结论:某条边的约束的倍数代表着这条边到相对边的距离的倍数
    //上面代码中的1.5倍让bottom边到y = 0边的距离变成了1.5倍
    

    相关文章

      网友评论

      • Gavin_peng:两篇读过之后都不错,赞
        MangoMade:@牵线小丑 这个我知道,,不过写这文章的那会儿还不知道
        牵线小丑:make.height.equalTo(50)
        make.width.equalTo(50)
        两句其实可以合成一句:
        make.width.height.equalTo(50)
        其他属性也类似
        MangoMade:@Gavin_peng 谢谢鼓励支持!

      本文标题:AutoLayout的那些事(二)

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