masonry(使用Masonry布局如何获取控件的frame值)_约束_控件_方法

历史故事本文相关内容:masonry so 约束 控件 方法

本文目录

  • 使用Masonry布局如何获取控件的frame值
  • Masonry自适应cell高度,同时实现cell折叠和展开
  • 使用masonry的时候怎么设置约束的优先级
  • masonry 优先级怎么使用
  • masonry能和xib结合使用吗
  • 【Masonry】详解以及三种约束方法与注意事项
  • xcode5怎么使用masonry
  • 使用masonry的一个坑
  • Masonry的使用

使用Masonry布局如何获取控件的frame值

在开发中,我们都会选择使用Masonry来做适配,但是有时我们又需要获取某个控件的frame,这时就会发现用Masonry布局的获取不到控件的frame。
这是因为用Masonry布局时控件的还没有在视图上展示出来,所以frame也就没有了,具体原理就得看Masonry实现的原理了,单用frame布局的就会有。
这时如果我们需要获取到frame的话就得刷新视图

这个方法将会刷新视图。在这个方法后就能获取frame

想要再深入了解的可以点这个链接看看
如果需要马上刷新可以在LayoutIfNeeded前加上setNeedsLayout

如果仅仅是想获取frame直接用layoutIfNeeded就可以了

Masonry自适应cell高度,同时实现cell折叠和展开

这都2017年了还在用frame布局实在是有点low了。。。
Autolayout自iOS6开始引入,到现在基本上也没什么坑了,就算有,前辈们也都填好了( ⁼̴̀ .̫ ⁼̴́ )✧

我理解的自动计算cell高度,有两个注意点:
第一: 设置tableView.estimatedRowHeight
self.tableView.estimatedRowHeight = 20

第二: 设置约束,保证cell的contentView的高度可以根据子控件算出来
例如以下只有一个label填充的cell(cell的结构-》cell--contentView--label)
只需要给label添加以下约束:

cell就可以自动计算自己的高度

下面的是我的想法过程,大家可以略过:
一开始的时候想的是给label一个高度小于等于120的约束,并且持有它
make.height.lessThanOrEqualTo(@120)
折叠的时候,把约束install,展开的时候uninstall。

实现起来:每次在TableView的cell点击代理方法里面 调用cell的方法使label高度的约束install和uninstall,然后调用 ;

后来发现和这个约束有冲突
make.bottom.equalTo(_contentLabel.superview.mas_bottom).with.offset(-20) ,作为强迫症患者这能忍?。
然后突然想到label的numberOfLines可以限制行数......这不就是现成的实现折叠/展开的最好方法吗...

test-autolayoutcell

1. Masonry
2. 优化UITableViewCell高度计算的那些事
3. iOS7和iOS8下的自适应cell

使用masonry的时候怎么设置约束的优先级

Masonry可以设置约束的优先级,优先级分为priorityHigh,priorityMedium,priorityLow(高,中等,低)三个等级。优先级默认为中等,所以当我们对某一个控件的约束条件重复后,会打印警告信息,告诉我们应该去修复它们。

[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@0).priorityHigh();

}];

当你使用masonry进行布局,运行的时候控制台如果有输出约束重复的话,可以用 .priorityHigh()将你想要布局的约束的优先级提高,就不会报约束重复了。

masonry 优先级怎么使用

自动布局最重要的是约束:UI元素间关系的数学表达式。约束包括尺寸、由优先级和阈值管理的相对位置。它们是添加剂,可能导致约束冲突 、约束不足造成布局无法确定 。这两种情况都会产生异常。

使用前:AutoLayout关于更新的几个方法的区别

setNeedsLayout:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。

layoutIfNeeded:告知页面布局立刻更新。所以一般都会和setNeedsLayout一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点一般布局动画可以在更新布局后直接使用这个方法让动画生效。

layoutSubviews:系统重写布局

setNeedsUpdateConstraints:告知需要更新约束,但是不会立刻开始

updateConstraintsIfNeeded:告知立刻更新约束

updateConstraints:系统更新约束

使用

  1. 基本使用

  2. mas_makeConstraints:添加约束

  3. mas_updateConstraints:更新约束、亦可添加新约束

  4. mas_remakeConstraints:重置之前的约束

  5. multipler属性表示约束值为约束对象的乘因数, dividedBy属性表示约束值为约束对象的除因数,可用于设置view的宽高比

  6. // 进行屏幕的适配的时候,往往需要根据屏幕宽度来适配一个相应的高度,在此使用如下约束的方式来进行控件的适配

  7. ;

  8. [self.topInnerView mas_makeConstraints:^(MASConstraintMaker *make) {

  9. make.height.equalTo(self.topView.mas_height).dividedBy(3);

  10. make.width.and.height.lessThanOrEqualTo(self.topView);

  11. make.width.and.height.equalTo(self.topView).with.priorityLow();

  12. make.center.equalTo(self.topView);

  13. }];

  14. priorityLow()设置约束优先级

  15. #define MAS_SHORTHAND_GLOBALS使用全局宏定义,可以使equalTo等效于mas_equalTo

  16. #define MAS_SHORTHAND使用全局宏定义, 可以在调用masonry方法的时候不使用mas_前缀

  17. // 这里注意到一个地方,就是当使用了这个全局宏定义之后,发现可以有个类`NSArray+MASAdditions.h`,看了之后发现可以

  18. self.buttonViews = @;

  19. // 之后可以在updateConstraints 方法中

  20. - (void)updateConstraints {

  21. [self.buttonViews updateConstraints:^(MASConstraintMaker *make) {

  22. make.baseline.equalTo(self.mas_centerY).with.offset(self.offset);

  23. }];

  24. ;  

  25. }

动态修改视图约束:

// 创建视图约束

[blueView mas_makeConstraints:^(MASConstraintMaker *make) {

self.animatableConstraint = make.edges.equalTo(superview).insets(paddingInsets).priorityLow();

]];

// 更改约束 (另一处方法中)

UIEdgeInsets paddingInsets = UIEdgeInsetsMake(padding, padding, padding, padding);

self.animatableConstraint.insets = paddingInsets;

;

debug模式:

// 对某个view添加key值

greenView.mas_key = @“greenView“;

// 或者如下顺序

MASAttachKeys(greenView, redView, blueView, superview);

// 同样的对每条约束亦可以添加key

make.height.greaterThanOrEqualTo(@5000).key(@“ConstantConstraint“);

preferredMaxLayoutWidth: 多行label的约束问题

// 已经确认好了位置

// 在layoutSubviews中确认label的preferredMaxLayoutWidth值

- (void)layoutSubviews {

;

// 你必须在 调用之后,longLabel的frame有值之后设置preferredMaxLayoutWidth

self.longLabel.preferredMaxLayoutWidth = self.frame.size.width-100;

// 设置preferredLayoutWidth后,需要重新布局

;

}

scrollView使用约束的问题:原理通过一个contentView来约束scrollView的contentSize大小,也就是说以子控件的约束条件,来控制父视图的大小

// 1. 控制scrollView大小(显示区域)

[self.scrollView makeConstraints:^(MASConstraintMaker *make) {

make.edges.equalTo(self.view);

}];

// 2. 添加一个contentView到scrollView,并且添加好约束条件

[contentView makeConstraints:^(MASConstraintMaker *make) {

make.edges.equalTo(self.scrollView);

// 注意到此处的宽度约束条件,这个宽度的约束条件是比添加项

make.width.equalTo(self.scrollView);

}];

// 3. 对contentView的子控件做好约束,达到可以控制contentView的大小

新方法:2个或2个以上的控件等间隔排序

/**

*  多个控件固定间隔的等间隔排列,变化的是控件的长度或者宽度值

*

*  @param axisType        轴线方向

*  @param fixedSpacing    间隔大小

*  @param leadSpacing     头部间隔

*  @param tailSpacing     尾部间隔

*/

- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType 

withFixedSpacing:(CGFloat)fixedSpacing l

eadSpacing:(CGFloat)leadSpacing 

tailSpacing:(CGFloat)tailSpacing;

/**

*  多个固定大小的控件的等间隔排列,变化的是间隔的空隙

*

*  @param axisType        轴线方向

*  @param fixedItemLength 每个控件的固定长度或者宽度值

*  @param leadSpacing     头部间隔

*  @param tailSpacing     尾部间隔

*/

- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType 

withFixedItemLength:(CGFloat)fixedItemLength 

leadSpacing:(CGFloat)leadSpacing 

tailSpacing:(CGFloat)tailSpacing;

使用方法很简单,因为它是NSArray的类扩展:

//  创建水平排列图标 arr中放置了2个或连个以上的初始化后的控件

//  alongAxis 轴线方向   固定间隔     头部间隔      尾部间隔

;

[arr makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(@60);

make.height.equalTo(@60);

}];

masonry能和xib结合使用吗

可以结合使用。
使用常规的Masonry语法完成布局的代码是这样的
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.mas_left).with.offset(0);
make.bottom.equalTo(self.view.mas_bottom).with.offset(0);
make.height.equalTo(@100);
}];

[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(redView.mas_right).with.offset(0);
make.bottom.equalTo(self.view.mas_bottom).with.offset(0);
make.width.equalTo(redView.mas_width).with.offset(0);
make.height.equalTo(redView.mas_height).with.offset(0);
}];

[greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(blueView.mas_right).with.offset(0);
make.bottom.equalTo(self.view.mas_bottom).with.offset(0);
make.right.equalTo(self.view.mas_right).with.offset(0);
make.width.equalTo(blueView.mas_width).with.offset(0);
make.height.equalTo(blueView.mas_height).with.offset(0);
}];
代码中可以看到具体的逻辑还是特别清晰的。可以清楚地了解各个控件间的关系,基本上每一行代表着xib中的一根约束。
并且Masonry支持了一些省略和简写:
如果是两个控件的同一个位置(约束)之间的联系,括号中可以只写以来的控件约束可以省略;
如果约束依赖的是同一个控件,那可以用and将两个约束连在一行写;
如果偏移量offset是0,后面的with.offset(0)可以省略;
将上面的代码最简可以写成如下
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.bottom.equalTo(self.view);
make.height.equalTo(@100);
}];

[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.and.width.and.height.equalTo(redView);
make.left.equalTo(redView.mas_right);
}];

[greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.and.width.and.height.equalTo(blueView);
make.right.equalTo(self.view);
make.left.equalTo(blueView.mas_right);
}];
注:对于这种几个模块功能相似位置相近的,建议多包一层父控件,便于整个组件的操作与抽离,并且可以从宏观的角度看项目结构更加清晰。

【Masonry】详解以及三种约束方法与注意事项

Masonry就是对系统 AutoLayout 进行的封装,包括里面很多的 API ,都是对系统 API 进行了一次二次包装。

方法1: offset() 方法,此法繁琐

方法2:通过 insets 简化设置内边距的方式,,此法简单

1: mas_makeConstraints
特点:只负责 新增 约束

2: mas_remakeConstraints
特点:会清除 当前对象 之前的所有约束,仅保留最 新的 约束

3: mas_updateConstraints
特点: 更新 对象的约束

注意: 同一个对象 使用 mas_updateConstraints 一定要保证 block 中要更新的元素是其使用 mas_makeConstraints 设置的约束

1,正确的示例:如下就是正确的,则不会出现约束冲突问题

2,错误的示例:但是下面的就不对了,就会出现约束冲突 在iOS 7 及其以下 会出现由于约束冲突出现的崩溃

例子2: mas_updateConstraints 使用

textLabel 只需要设置一个属性即可

使用基础数据类型当做参数

设置约束优先级

设置约束比例

子视图 等高/等宽 练习

子视图垂直居中练习

xcode5怎么使用masonry

首先,在正式使用Masonry之前,我们先来看看在xib中我们是如何使用AutoLayout
可以看出,只要设置相应得局限,控制好父视图与子视图之间的关系就应该很ok的拖出你需要的需求。这里就不详细讲解具体拖拽的方法.....
然后,我们按着上图的属性来看看如何简单得使用Masonry
这里是Masonry给我们的属性
@property (nonatomic, strong, readonly) MASConstraint *left; //左侧
@property (nonatomic, strong, readonly) MASConstraint *top; //上侧
@property (nonatomic, strong, readonly) MASConstraint *right; //右侧
@property (nonatomic, strong, readonly) MASConstraint *bottom; //下侧
@property (nonatomic, strong, readonly) MASConstraint *leading; //首部
@property (nonatomic, strong, readonly) MASConstraint *trailing; //尾部
@property (nonatomic, strong, readonly) MASConstraint *width; //宽
@property (nonatomic, strong, readonly) MASConstraint *height; //高
@property (nonatomic, strong, readonly) MASConstraint *centerX; //横向居中
@property (nonatomic, strong, readonly) MASConstraint *centerY; //纵向居中
@property (nonatomic, strong, readonly) MASConstraint *baseline; //文本基线
属性有了,接着我们应该怎么在视图中添加约束呢,Masonry给我们提供了3个方法
//新增约束
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
//更新约束
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;
//清楚之前的所有约束,只会保留最新的约束
- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;

合理的利用这个3个函数,基本上可以应对任何情况了
准备工作已经完成,我们来看几个小demo
1.居中一个view
// 防止block中的循环引用
__weak typeof (self) weakSelf = self;
// 初始化一个View
UIView *bgView = ;
bgView.backgroundColor = ;
;
// 使用mas_makeConstraints添加约束
[bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(weakSelf.view);
make.size.mas_equalTo(CGSizeMake(200, 200));
}];

使用masonry的一个坑

示例:
有一个 tableview ,上面有 cell , cell 上面有一个 UILabel ,这个 UILabel 的高度 height 是由数据源中计算得来,那么在处理数据源的方法

中做这个 UILabel 的约束时如果采用相对约束:

则没有问题。

如果采用绝对约束:即直接设置高度,而不是设置底部对齐:

这样由于 cell 的复用性,在下一次复用这个 cell 的时候, masonry 不会再去重新设置这个 height ,但是 height 又由于数据源不一样而需要改变,就导致了显示错误。此时将 mas_makeConstraints 的方式改为 mas_remakeConstraints 的方式即可:

Masonry的使用

以下的所有内容都是摘抄至不同的网络文章。

首先对于Masonry的使用本人还是比较支持的,在iPhone6 和 6p出现后,也是势在必行。

感谢一下作者的帮助:

Masonry使用
其中的精华无非就是注意点而已,一下就是我个人觉得对我帮助最大的地方。

Masonry使用讲解
mas_makeConstraints 是给view添加约束,约束有几种,分别是边距,宽,高,左上右下距离,基准线。添加过约束后可以有修正,修正 有offset(位移)修正和multipliedBy(倍率)修正

语法一般是 make.equalTo or make.greaterThanOrEqualTo or make.lessThanOrEqualTo + 倍数和位移修正

注意点1: 使用 mas_makeConstraints方法的元素必须事先添加到父元素的中,例如;

注意点2: masequalTo 和 equalTo 区别:masequalTo 比equalTo多了类型转换操作,一般来说,大多数时候两个方法都是 通用的,但是对于数值元素使用mas_equalTo。对于对象或是多个属性的处理,使用equalTo。特别是多个属性时,必须使用equalTo,例如 make.left.and.right.equalTo(self.view);

注意点3: 注意到方法with和and,这连个方法其实没有做任何操作,方法只是返回对象本身,这这个方法的左右完全是为了方法写的时候的可读性 。make.left.and.right.equalTo(self.view);和make.left.right.equalTo(self.view);是完全一样的,但是明显的加了and方法的语句可读性 更好点。

特别声明

本文仅代表作者观点,不代表本站立场,本站仅提供信息存储服务。

分享:

扫一扫在手机阅读、分享本文