iOS AutoLayout中的Content Hugging

作者: 萌小菜 | 来源:发表于2016-02-02 18:22 被阅读8455次

    关于autolayout的优先级的问题在网上已经有很多资料了,推荐一个:
    Autolayout中关于intrinsic content、相关优先级及其应用

    这篇文章详细讲解了在使用storyboard中如何设置Content Hugging 和 Content Compression的优先级,我这里我就说下怎么使用代码设置优先级作为补充。用代码设置布局一般都使用masonry,所以我就在使用masonry的基础上写demo。


    添加两个label

        UILabel* leftLabel = [[UILabel alloc] init];
        leftLabel.backgroundColor = [UIColor redColor];
        [self.view addSubview:leftLabel];
        leftLabel.text = @"人做的畜生之事越多,内心越是痛苦。";
        [leftLabel sizeToFit];
        
        UILabel* rightLabel = [[UILabel alloc] init];
        rightLabel.backgroundColor = [UIColor greenColor];
        [self.view addSubview:rightLabel];
        rightLabel.text = @"1234567890";
        [rightLabel sizeToFit];
    

    设置布局

        [leftLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(@(20));
            make.left.equalTo(self.view).offset(10);
            make.centerY.equalTo(self.view);
            make.right.mas_lessThanOrEqualTo(rightLabel.mas_left);
        }];
        
        [rightLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(@(20));
            make.left.mas_greaterThanOrEqualTo(leftLabel.mas_right);
            make.right.equalTo(self.view).offset(-10);
            make.centerY.equalTo(leftLabel);
        }];
    

    运行效果

    0.png

    在默认情况下,我们没有设置各个布局的优先级,那么他就会优先显示左边的label,左边的完全显示后剩余的空间都是右边的label,如果整个空间宽度都不够左边的label的话,那么右边的label没有显示的机会了。

    如果我们现在的需求是优先显示右边的label,左边的label内容超出的省略,这时就需要我们调整约束的优先级了。

    理论

    • 约束优先级: 在Autolayout中每个约束都有一个优先级, 优先级的范围是1 ~ 1000。创建一个约束,默认的优先级是最高的1000
    • Content Hugging Priority: 该优先级表示一个控件抗被拉伸的优先级。优先级越高,越不容易被拉伸,默认是250。
    • Content Compression Resistance Priority: 该优先级和上面那个优先级相对应,表示一个控件抗压缩的优先级。优先级越高,越不容易被压缩,默认是750

    所以默认情况下两边的label的Content HuggingContent Compression优先级都是一样的,为了让右边的label完全显示,那么我们需要增大右边label的抗压缩级,或者减小左边label的抗压缩级,总之是得让右边的抗压缩级大于左边的label,这样才能让右边的label内容优先显示。

    UIView中关于Content Hugging 和 Content Compression Resistance的方法有:

    - (UILayoutPriority)contentHuggingPriorityForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
    - (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
    
    - (UILayoutPriority)contentCompressionResistancePriorityForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
    - (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
    

    在初始化label里面添加代码:

    [leftLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
    

    或者

    [rightLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
    

    UILayoutPriority类型实际上就是float类型,只要设置右边的比左边的大就可以。

    修改后的效果

    1.png
    对于多个labe或者button利用类似的方法都可以做到优先显示某一个控件的内容。

    相关文章

      网友评论

      • 强子ly:卧槽,面试的时候总是常说,熟练使用autolayout,妈的,在这卡了一下子,牛逼
        萌小菜:@强子ly 哈哈,加油
      • fruit6:文案深刻
      • 知行合一认知升级:6666666666效果好
      • 名扬丶四海:内容吸附(Content Hugging)的默认优先级是250吧,不是251
        萌小菜:@fisherv1 如果UIImageView的宽度固定的话,可以设置UILbel的right.equalorlessthan().offset(UIImageView的宽度)
        58edf48d0954:你好,如果是前面是UILbel, 后面是UIImageView,如何能确保 image 紧跟着uilabel。如果uilabel的文字太多,imageview 不会被挤出屏幕了。 如果文字很少, imageview 紧跟着uilabel后面吗。
        萌小菜:的确是250, 感谢指正。:pray:
      • a90a147abe6d:那 “ Content Hugging”的具体用法呢?
        liangdahong:Content Hugging : 内容拥抱,主要适用于当不满足正常情况时,需要控件必须强制拉伸来满足条件,那么 Content Hugging 越高就不容易拉伸。就拉伸其他的控件。

        Content Compression Resistance:内容抗压缩,主要适用于当不满足正常情况时,需要控件必须强制压缩来满足条件,那么 Content Compression Resistance 越高就不容易压缩。就压缩其他的控件。
        萌小菜:@摩西摩西和辛巴 用法是一样的 一个是抗压缩 这个是抗拉伸

      本文标题:iOS AutoLayout中的Content Hugging

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