一个约束优先级解说
http://www.cnblogs.com/siasyl/p/6775055.html
如果想要约束变换之后实现动画效果,则需要执行如下操作
// 通知需要更新约束,但是不立即执行
[self setNeedsUpdateConstraints];
// 立即更新约束,以执行动态变换
// update constraints now so we can animate the change
[self updateConstraintsIfNeeded];
// 执行动画效果, 设置动画时间
[UIView animateWithDuration:0.4 animations:^{
[self layoutIfNeeded];
}];
Masonry 动画 更新或者重置动画
然后用UIView 动画
UIView.animate(withDuration: 0.5, animations: {
self.controlBar.layoutIfNeeded()
self.topbar.layoutIfNeeded()
}) { (bool) in
self.topbar.isHidden = isHidden
self.controlBar.isHidden = isHidden
}
Masonry的更新约束 mas_updateConstraints 更新约束 但是约束的相对实例不能变
mas_makeConstraints 删除以前的约束用新的约束
要求:
当键盘挡住输入框时,输入框自动向上弹到键盘上方。
实现:
这里需要使用到Masonry的另外一个方法mas_updateConstraints。这个方法用于更新控件约束。
具体的实现方式可以下载Demo来看,这里只贴出键盘弹出时的处理代码:
swift
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardChangeFrame(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardHid(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardChangeFrame(_ sender:Notification){
var keyHeight:CGFloat = 246
var info = (sender as NSNotification).userInfo //as? NSDictionary
let keyboardSize = (info?[UIKeyboardFrameBeginUserInfoKey] as AnyObject).cgRectValue //UIKeyboardFrameEndUserInfoKey UIKeyboardFrameBeginUserInfoKey
let keyboardDuration = (info?[UIKeyboardAnimationDurationUserInfoKey] as AnyObject).doubleValue ?? 0
if keyboardSize != nil{
keyHeight = (keyboardSize!.height)
}
self.searchAssociative.mas_updateConstraints { (make) in
make?.bottom.mas_equalTo()(self.view)?.offset()(-keyHeight)
}
UIView.animate(withDuration: keyboardDuration) {
self.view.layoutIfNeeded()
}
}
- (void)keyboardWillChangeFrameNotification:(NSNotification *)notification {
// 获取键盘基本信息(动画时长与键盘高度)
NSDictionary *userInfo = [notification userInfo];
CGRect rect = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat keyboardHeight = CGRectGetHeight(rect);
CGFloat keyboardDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// 修改下边距约束
[_textField mas_updateConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(-keyboardHeight);
}];
// 更新约束
[UIView animateWithDuration:keyboardDuration animations:^{
[self.view layoutIfNeeded];
}];
}
由于业务需要,有时候需要动态加载Cell,考虑一些方案后采取把Cell高度设置为0.01的方法。但是约束为-10 的话会有错误信息(据说ios7 会崩溃) ,解决方法是降低优先级
self.titleLabel.mas_makeConstraints({ (make) in
make?.top.mas_equalTo()(self.imageView.mas_bottom)?.offset()(interval_W_10)?.priority()(499)
make?.left.right().mas_equalTo()(self.imageView)
make?.bottom.mas_equalTo()(self)?.offset()(-interval_W_10)?.priority()(499)
})
From: http://www.jianshu.com/p/a24dd8638d28
个人喜欢用纯代码写东西,其中用到最多的就是Masonry,我整理一些使用过程中一些点,方便以后使用.(基本的语法就不说了)
首先说几点:
-
我一般将数值类型的约束用
mas_equalTo
,而相对于某个控件,或者某个控件的某个约束,我会使用equalTo
,如:
make.size.mas_equalTo(CGSizeMake(100, 100));
make.center.equalTo(weakSelf.view);
-
setNeedsLayout
:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。
layoutIfNeeded
:告知页面布局立刻更新。所以一般都会和setNeedsLayout
一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点一般布局动画可以在更新布局后直接使用这个方法让动画生效。
layoutSubviews
:系统重写布局
setNeedsUpdateConstraints
:告知需要更新约束,但是不会立刻开始
updateConstraintsIfNeeded
:告知立刻更新约束
updateConstraints
:系统更新约束 -
- (void)updateViewConstraints
ViewController的View在更新视图布局时,会先调用ViewController的updateViewConstraints 方法。我们可以通过重写这个方法去更新当前View的内部布局,而不用再继承这个View去重写-updateConstraints方法。我们在重写这个方法时,务必要调用 super 或者 调用当前View的 -updateConstraints 方法。// 防止block中的循环引用
__weak typeof(self) weakSelf = self;
UIView* view = [UIView new];
view.backgroundColor = [UIColor brownColor];
[self.view addSubview:view];
//使用mas_makeConstraints添加约束
[view mas_makeConstraints:^(MASConstraintMaker *make) {// 添加大小约束(make就是要添加约束的控件view)
make.size.mas_equalTo(CGSizeMake(200, 200));// 添加居中约束(居中方式与self相同)
make.center.equalTo(weakSelf.view);
}];UIView* blackView = [UIView new];
blackView.backgroundColor = [UIColor blackColor];
[self.view addSubview:blackView];
[blackView mas_makeConstraints:^(MASConstraintMaker *make) {
//添加约束大小
make.size.mas_equalTo(CGSizeMake(100, 100));
//在 左,上 添加约束 (左、上约束都是20)
make.left.and.top.mas_equalTo(20);
}];
UIView* grayView = [UIView new];
grayView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:grayView];
[grayView mas_makeConstraints:^(MASConstraintMaker *make) {
// 大小、上边距约束与黑色view相同
make.size.and.top.equalTo(blackView);
// 添加右边距约束(这里的间距是有方向性的,左、上边距约束为正数,右、下边距约束为负数)
make.right.mas_equalTo(-20);
}];
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
__weak typeof(self) weakSelf = self;
_textField = [UITextField new];
_textField.backgroundColor = [UIColor redColor];
[self.view addSubview:_textField];
[_textField mas_makeConstraints:^(MASConstraintMaker *make) {
//left,right,centerx,y 不能共存只能有其二
make.left.mas_equalTo(20);
// make.right.mas_equalTo(-60);
make.centerX.equalTo(weakSelf.view);
make.height.mas_equalTo(40);
make.bottom.mas_equalTo(0);
}];
// 注册键盘通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrameNotification:) name:UIKeyboardWillChangeFrameNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideNotification:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillChangeFrameNotification:(NSNotification *)notification {
// 获取键盘基本信息(动画时长与键盘高度)
NSDictionary *userInfo = [notification userInfo];
CGRect rect = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat keyboardHeight = CGRectGetHeight(rect);
CGFloat keyboardDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// 修改下边距约束
[_textField mas_updateConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(-keyboardHeight);
}];
// 更新约束
[UIView animateWithDuration:keyboardDuration animations:^{
[self.view layoutIfNeeded];
}];
}
- (void)keyboardWillHideNotification:(NSNotification *)notification {
// 获得键盘动画时长
NSDictionary *userInfo = [notification userInfo];
CGFloat keyboardDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// 修改为以前的约束(距下边距0)
[_textField mas_updateConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(0);
}];
// 更新约束
[UIView animateWithDuration:keyboardDuration animations:^{
[self.view layoutIfNeeded];
}];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.view endEditing:YES];
}
方法一:
array 的 mas_distributeViewsAlongAxis withFixedSpacing
变化的是控件 长度或宽度
定义一个存放三个控件的数组NSArray *array;
array = @[greenView,redView,blueView];
注意:
数组里面的元素不能小于2个,要不会报错 views to distribute need to bigger than one
直接调用下面的方法:
- (void)getHorizontalone
{
//方法一,array 的 mas_distributeViewsAlongAxis
/**
* 多个控件固定间隔的等间隔排列,变化的是控件的长度或者宽度值
*
* @param axisType 轴线方向
* @param fixedSpacing 间隔大小
* @param leadSpacing 头部间隔
* @param tailSpacing 尾部间隔
*/
// MASAxisTypeHorizontal 水平
// MASAxisTypeVertical 垂直
[arrayList mas_distributeViewsAlongAxis:MASAxisTypeHorizontal
withFixedSpacing:20
leadSpacing:5
tailSpacing:5];
[arrayList mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(60);
make.height.mas_equalTo(100);
}];
}
方法二:
array de mas_distributeViewsAlongAxis withFixedItemLength
控件size不变,变化的是间隙
- (void)getVertical
{
/**
* 多个固定大小的控件的等间隔排列,变化的是间隔的空隙
*
* @param axisType 轴线方向
* @param fixedItemLength 每个控件的固定长度或者宽度值
* @param leadSpacing 头部间隔
* @param tailSpacing 尾部间隔
*/
[arrayList mas_distributeViewsAlongAxis:MASAxisTypeVertical
withFixedItemLength:60
leadSpacing:40
tailSpacing:10];
[arrayList mas_makeConstraints:^(MASConstraintMaker *make) {
// make.top.mas_equalTo(100);
// make.height.mas_equalTo(100);
make.left.mas_equalTo(20);
make.right.mas_equalTo(-20);
}];
}
NSArray+MASAdditions
中
以上俩方法都在 方法三:直接设置multiplier
实现等间距
for (NSUInteger i = 0; i < 4; i++) {
UIView *itemView = [self getItemViewWithIndex:i];
[_containerView addSubview:itemView];
[itemView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.and.height.equalTo(@(ITEM_SIZE));
make.centerY.equalTo(_containerView.mas_centerY);
make.centerX.equalTo(_containerView.mas_right).multipliedBy(((CGFloat)i + 1) / ((CGFloat)ITEM_COUNT + 1));
}];
}
方法四: 利用透明等宽度的SpaceView实现等间距
UIView *lastSpaceView = [UIView new];
lastSpaceView.backgroundColor = [UIColor greenColor];
[_containerView1 addSubview:lastSpaceView];
[lastSpaceView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.top.and.bottom.equalTo(_containerView1);
}];
for (NSUInteger i = 0; i < ITEM_COUNT; i++) {
UIView *itemView = [self getItemViewWithIndex:i];
[_containerView1 addSubview:itemView];
[itemView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.and.width.equalTo(@(ITEM_SIZE));
make.left.equalTo(lastSpaceView.mas_right);
make.centerY.equalTo(_containerView1.mas_centerY);
}];
UIView *spaceView = [UIView new];
spaceView.backgroundColor = [UIColor greenColor];
[_containerView1 addSubview:spaceView];
[spaceView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(itemView.mas_right).with.priorityHigh(); // 降低优先级,防止宽度不够出现约束冲突
make.top.and.bottom.equalTo(_containerView1);
make.width.equalTo(lastSpaceView.mas_width);
}];
lastSpaceView = spaceView;
}
[lastSpaceView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(_containerView1.mas_right);
}];
和面方法4一样,利用spaceView来实现
UIView* bgView = [[UIView alloc]init];
bgView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:bgView];
[bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.mas_equalTo(0);
make.top.mas_equalTo(@100);
make.height.mas_equalTo(@100);
}];
listText = @[@"北京",@"地大吴波啊",@"你大爷",@"我们的爱哎哎"];
UIView *lastSpaceView = nil;
for(int i = 0 ; i < listText.count; i ++)
{
UILabel* label = [UILabel new];
label.text = listText[i];
label.backgroundColor = RANDOMCOLOR;
[bgView addSubview:label];
UIView* lineView = [UIView new];
lineView.backgroundColor = [UIColor redColor];
[bgView addSubview:lineView];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.mas_equalTo(0);
if (lastSpaceView)
{
NSLog(@"存在 lastView");
make.left.equalTo(lastSpaceView.mas_right).mas_offset(@20);
}else
{
NSLog(@"不存在存在 lastView");
make.left.equalTo(bgView.mas_left);
}
make.height.equalTo(bgView);
}];
lastSpaceView = label;
[lineView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.bottom.mas_equalTo(0);
make.width.mas_equalTo(1);
make.left.mas_equalTo(label.mas_right).mas_offset(@10);
}];
}
UIView* bgView = [UIView new];
bgView.backgroundColor = [UIColor purpleColor];
[self.view addSubview:bgView];
UILabel* titleLab = [UILabel new];
titleLab.backgroundColor = [UIColor redColor];
titleLab.textAlignment = NSTextAlignmentCenter;
titleLab.font = [UIFont systemFontOfSize:15.f];
titleLab.text = @"曹操——《短歌行》";
[bgView addSubview:titleLab];
UILabel* contentLab = [UILabel new];
contentLab.numberOfLines = 0 ;
contentLab.textAlignment = NSTextAlignmentCenter;
contentLab.backgroundColor = [UIColor brownColor];
contentLab.font = [UIFont systemFontOfSize:13.f];
contentLab.text = @" 对酒当歌,人生几何? 譬如朝露,去日苦多。\n 慨当以慷,忧思难忘。 何以解忧?唯有杜康。\n 青青子衿,悠悠我心。 但为君故,沉吟至今。\n 呦呦鹿鸣,食野之苹。 我有嘉宾,鼓瑟吹笙。\n 明明如月,何时可掇? 忧从中来,不可断绝。\n 越陌度阡,枉用相存。 契阔谈宴,心念旧恩。\n 月明星稀,乌鹊南飞。 绕树三匝,何枝可依?\n 山不厌高,海不厌深。 周公吐哺,天下归心。";
[bgView addSubview:contentLab];
//思路: 父视图的上间距等于title的上间距,父视图的下间距等于content的下间距
__weak typeof(self) weakSelf = self;
[bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_offset(@30);
make.right.mas_offset(@-30);
make.centerY.equalTo(weakSelf.view);
}];
[titleLab mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.mas_equalTo(@0);
}];
[contentLab mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(@0);
make.top.equalTo(titleLab.mas_bottom).mas_offset(@10);
make.bottom.equalTo(bgView);
}];
以后慢慢更新,记录方便以后使用
文/栋飞
//一些扒的别人的记录
自适应布局允许将宽度或高度设置为固定值.如果你想要给视图一个最小或最大值,你可以这样:
//width >= 200 && width <= 400 make.width.greaterThanOrEqualTo(@200); make.width.lessThanOrEqualTo(@400)
约束的优先级
.priority
允许你指定一个精确的优先级,数值越大优先级越高.最高1000.
.priorityHigh
等价于 UILayoutPriorityDefaultHigh
.优先级值为 750.
.priorityMedium
介于高优先级和低优先级之间,优先级值在 250~750之间.
.priorityLow
等价于 UILayoutPriorityDefaultLow
, 优先级值为 250.
优先级可以在约束的尾部添加:
make.left.greaterThanOrEqualTo(label.mas_left).with.priorityLow();
make.top.equalTo(label.mas_top).with.priority(600);
center 中心
//使 centerX和 centerY = button1
make.center.equalTo(button1)
//使 centerX = superview.centerX - 5, centerY = superview.centerY + 10 make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10))
指定宽度为父视图的 1/4.
make.width.equalTo(superview).multipliedBy(0.25);
Masonry框架初次使用遇到的坑 frame为0
From: http://www.jianshu.com/p/ad9c075a7547
实现自适应布局的一个非常方便的方法就是使用Masonry框架,然而使用Masonry布局的时候,并不能立刻反应到frame
的改变上,比如:
UIView *parent = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
UIImageView *child = [UIView alloc] init];
[parent addSubview:child];
[child mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(20,20));
make.top.left.mas_equalTo(50);
}];
NSLog(@"%@",redView);
打印结果:
** <UIImageView: 0x7fb222605550; frame = (0 0; 0 0); layer = <CALayer: 0x7fb22260b3a0>>**
可以发现,虽然使用Masonry进行布局和约束,但是子视图child
的frame
仍然为(0, 0, 0 ,0).
而这时候如果有需求要设置child的形状为圆形,就得知道它的frame,像下面这样写肯定不会设置成功的:
[child mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(20,20));
make.top.left.mas_equalTo(50);
}];
child.layer.cornerRadius = child.bounds.size.width/2;
child.layer.masksToBounds = YES; //设置头像为圆形
因为这时候的frame还是0。我想会不会是因为block中的处理是放在另一个线程中异步进行的,block还没执行完就已经走到了下面使用frame的代码,(一阵狂喜,好聪明。。。),所以马上把代码改写:
[child mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(20,20));
make.top.left.mas_equalTo(50);
child.layer.cornerRadius = child.bounds.size.width/2;
child.layer.masksToBounds = YES; //设置头像为圆形
}];
然而并没有什么卵用。。。
没办法只能问谷歌了,然后找到了Masonry约束下获取frame
的方法:
使用masonry的实质还是调用了ios7以后的autolayout,如果要更新frame
,需要调用layoutIfNeeded
函数进行布局,然后所约束的控件才会按照约束条件,生成当前布局相应的frame
和bounds
。这样就可以利用这两个属性来进行图片圆角剪裁。而调用layoutIfNeeded
的目的是让系统调用layoutSubviews
方法,我们也可以直接在这个方法里获取frame,因为这时候开始layout subviews,Masonry已经计算出了真实的frame。
下面附上关于autolayout更新几个方法的区别:
setNeedsLayout:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。
layoutIfNeeded:告知页面布局立刻更新。所以一般都会和setNeedsLayout一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点,动画可以在更新布局后直接使用这个方法让动画生效。
layoutSubviews:系统重写布局
setNeedsUpdateConstraints:告知需要更新约束,但是不会立刻开始
updateConstraintsIfNeeded:告知立刻更新约束
updateConstraints:系统更新约束
From: http://www.cnblogs.com/gfxxbk/p/5827301.html
1、Masonry概述
- 目前最流行的Autolayout第三方框架
用优雅的代码方式编写Autolayout
省去了苹果官方恶心的Autolayout代码
大大提高了开发效率
2、常用方法
-
这个方法只会添加新的约束
[blueView mas_makeConstraints:^(MASConstraintMaker *make) { }];
-
这个方法会将以前的所有约束删掉,添加新的约束
[blueView mas_remakeConstraints:^(MASConstraintMaker *make) { }];
-
这个方法将会覆盖以前的某些特定的约束
[blueView mas_updateConstraints:^(MASConstraintMaker *make) {
}];
3、约束类型
- 尺寸:
width(宽)\height(高)\size(大小)
// 宽度约束
make.width.mas_equalTo(100);
// 高度约束
make.height.mas_equalTo(100);
// 大小约束(与上面两句等价)
make.size.mas_equalTo(CGSizeMake(100, 100));
- 边界:
left\leading(左边界)\right\trailing(右边界)\top(顶部边界)\bottom(底部边界)
// 左边(leading类似)
make.left.mas_equalTo(self.view).offset(50);
// 右边(trailing类似)
make.right.equalTo(self.view).offset(-20);
// 顶部
make.top.equalTo(self.view).offset(20);
// 底部
make.bottom.mas_equalTo(self.view).offset(-50);
- 中心点:
center\centerX\centerY
// 居中(水平+垂直)
// 尺寸是父控件的一半
[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(self.view).multipliedBy(0.5);
make.center.mas_equalTo(self.view); // 与下面两句代码等价
// make.centerX.mas_equalTo(self.view);
// make.centerY.mas_equalTo(self.view);
}];
- 内边距实现边界约束:
edges
// UIEdgeInsets 内边距
make.edges.mas_equalTo(self.view).insets(UIEdgeInsetsMake(50, 50, 50, 50));
4、mas_前缀修饰与不修饰的区别
- mas_equalTo和equalTo
默认情况下:
mas_equalTo有自动包装功能,比如自动将20包装为@20
equalTo没有自动包装功能
mas_equalTo的功能强于 > equalTo,可以一直使用mas_equalTo
- mas_width和width
默认情况下:
width是make对象的一个属性,用来添加宽度约束用的,表示对宽度进行约束
mas_width是一个属性值,用来当做equalTo的参数,表示某个控件的宽度属性
mas_height、mas_centerX以此类推
- 消除区别办法
如果添加了下面的宏,那么 mas_equalTo 和 equalTo 就没有区别
#define MAS_SHORTHAND_GLOBALS // 注意:这个宏一定要添加到#import "Masonry.h"前面
如果添加了下面的宏,mas_width也可以写成width
#define MAS_SHORTHAND
//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"
- (void)viewDidLoad {
[super viewDidLoad];
// 蓝色控件
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];
// 红色控件
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
// 添加约束
CGFloat margin = 20;
CGFloat height = 50;
[blueView makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.left).offset(margin);
make.right.equalTo(redView.left).offset(-margin);
make.bottom.equalTo(self.view.bottom).offset(-margin);
make.height.equalTo(height);
make.top.equalTo(redView.top);
make.bottom.equalTo(redView.bottom);
make.width.equalTo(redView.width);
}];
[redView makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view.right).offset(-margin);
}];
}
5、可有可无的用法
以下方法都仅仅是为了提高可读性,可有可无
-
with
- (MASConstraint*)with {
return self;
}
- (MASConstraint*)with {
使用情况示例代码
// 尺寸限制:100x100
// 位置:粘着父控件右下角,间距是20
[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
// 宽度约束
make.width.equalTo(@100);
// 高度约束
make.height.equalTo(@100);
// 右边
make.right.equalTo(self.view.mas_right).with.offset(-20);
// 顶部
make.top.equalTo(self.view.mas_top).with.offset(20);
}];
-
and
- (MASConstraint*)and {
return self;
}
- (MASConstraint*)and {
使用情况示例代码
// 尺寸限制:100x100
// 位置:粘着父控件右下角,间距是20
[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
// 宽度高度约束
make.width.and.height.mas_equalTo(100);
// 右边
make.right.equalTo(self.view).offset(-20);
// 顶部
make.top.equalTo(self.view).offset(20);
}];
From: http://liuyanwei.jumppo.com/2015/06/14/ios-library-masonry.html
Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布局 简洁明了 并具有高可读性 而且同时支持 iOS 和 Max OS X。 Masonry是一个用代码写iOS或os界面的库,可以代替Auto layout。 Masonry的github地址:https://github.com/SnapKit/Masonry
本章内容
-
* Masonry配置
-
* Masonry使用
-
* Masonry实例
Masonry配置
-
* 推荐使用pods方式引入类库,pod ‘Masonry’,若不知道pod如何使用,情况我的另一篇文章: [提高iOS开发效率的工具][1]
-
* 引入头文件 #import “Masonry.h”
Masonry使用讲解
-
mas_makeConstraints 是给view添加约束,约束有几种,分别是边距,宽,高,左上右下距离,基准线。添加过约束后可以有修正,修正 有offset(位移)修正和multipliedBy(倍率)修正
-
语法一般是 make.equalTo or make.greaterThanOrEqualTo or make.lessThanOrEqualTo + 倍数和位移修正
-
注意点1: 使用 mas_makeConstraints方法的元素必须事先添加到父元素的中,例如[self.view addSubview:view];
-
注意点2: mas_equalTo 和 equalTo 区别:mas_equalTo 比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方法的语句可读性 更好点。
Masonry初级使用例子
// exp1: 中心点与self.view相同,宽度为400*400
-(void)exp1{
UIView *view = [UIView new];
[view setBackgroundColor:[UIColor redColor]];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(400,400));
}];
}
//exp2: 上下左右边距都为10
-(void)exp2{
UIView *view = [UIView new];
[view setBackgroundColor:[UIColor redColor]];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
// make.left.equalTo(self.view).with.offset(10);
// make.right.equalTo(self.view).with.offset(-10);
// make.top.equalTo(self.view).with.offset(10);
// make.bottom.equalTo(self.view).with.offset(-10);
}];
}
//exp3 让两个高度为150的view垂直居中且等宽且等间隔排列 间隔为10
-(void)exp3{
UIView *view1 = [UIView new];
[view1 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:view1];
UIView *view2 = [UIView new];
[view2 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:view2];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.view.mas_centerY);
make.height.mas_equalTo(150);
make.width.mas_equalTo(view2.mas_width);
make.left.mas_equalTo(self.view.mas_left).with.offset(10);
make.right.mas_equalTo(view2.mas_left).offset(-10);
}];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.view.mas_centerY);
make.height.mas_equalTo(150);
make.width.mas_equalTo(view1.mas_width);
make.left.mas_equalTo(view1.mas_right).with.offset(10);
make.right.equalTo(self.view.mas_right).offset(-10);
}];
}
Masonry例子-计算器布局
![][2]
[2]: http://liuyanwei.jumppo.com/assets/uploads/masonry_1.png
//高级布局练习 iOS自带计算器布局
-(void)exp4{
//申明区域,displayView是显示区域,keyboardView是键盘区域
UIView *displayView = [UIView new];
[displayView setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:displayView];
UIView *keyboardView = [UIView new];
[self.view addSubview:keyboardView];
//先按1:3分割 displView(显示结果区域)和 keyboardView(键盘区域)
[displayView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.mas_top);
make.left.and.right.equalTo(self.view);
make.height.equalTo(keyboardView).multipliedBy(0.3f);
}];
[keyboardView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(displayView.mas_bottom);
make.bottom.equalTo(self.view.mas_bottom);
make.left.and.right.equalTo(self.view);
}];
//设置显示位置的数字为0
UILabel *displayNum = [[UILabel alloc]init];
[displayView addSubview:displayNum];
displayNum.text = @"0";
displayNum.font = [UIFont fontWithName:@"HeiTi SC" size:70];
displayNum.textColor = [UIColor whiteColor];
displayNum.textAlignment = NSTextAlignmentRight;
[displayNum mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.equalTo(displayView).with.offset(-10);
make.bottom.equalTo(displayView).with.offset(-10);
}];
//定义键盘键名称,?号代表合并的单元格
NSArray *keys = @[@"AC",@"+/-",@"%",@"÷"
,@"7",@"8",@"9",@"x"
,@"4",@"5",@"6",@"-"
,@"1",@"2",@"3",@"+"
,@"0",@"?",@".",@"="];
int indexOfKeys = 0;
for (NSString *key in keys){
//循环所有键
indexOfKeys++;
int rowNum = indexOfKeys %4 ==0? indexOfKeys/4:indexOfKeys/4 +1;
int colNum = indexOfKeys %4 ==0? 4 :indexOfKeys %4;
NSLog(@"index is:%d and row:%d,col:%d",indexOfKeys,rowNum,colNum);
//键样式
UIButton *keyView = [UIButton buttonWithType:UIButtonTypeCustom];
[keyboardView addSubview:keyView];
[keyView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[keyView setTitle:key forState:UIControlStateNormal];
[keyView.layer setBorderWidth:1];
[keyView.layer setBorderColor:[[UIColor blackColor]CGColor]];
[keyView.titleLabel setFont:[UIFont fontWithName:@"Arial-BoldItalicMT" size:30]];
//键约束
[keyView mas_makeConstraints:^(MASConstraintMaker *make) {
//处理 0 合并单元格
if([key isEqualToString:@"0"] || [key isEqualToString:@"?"] ){
if([key isEqualToString:@"0"]){
[keyView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(keyboardView.mas_height).with.multipliedBy(.2f);
make.width.equalTo(keyboardView.mas_width).multipliedBy(.5);
make.left.equalTo(keyboardView.mas_left);
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.9f);
}];
}if([key isEqualToString:@"?"]){
[keyView removeFromSuperview];
}
}
//正常的单元格
else{
make.width.equalTo(keyboardView.mas_width).with.multipliedBy(.25f);
make.height.equalTo(keyboardView.mas_height).with.multipliedBy(.2f);
//按照行和列添加约束,这里添加行约束
switch (rowNum) {
case 1:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.1f);
keyView.backgroundColor = [UIColor colorWithRed:205 green:205 blue:205 alpha:1];
}
break;
case 2:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.3f);
}
break;
case 3:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.5f);
}
break;
case 4:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.7f);
}
break;
case 5:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.9f);
}
break;
default:
break;
}
//按照行和列添加约束,这里添加列约束
switch (colNum) {
case 1:
{
make.left.equalTo(keyboardView.mas_left);
}
break;
case 2:
{
make.right.equalTo(keyboardView.mas_centerX);
}
break;
case 3:
{
make.left.equalTo(keyboardView.mas_centerX);
}
break;
case 4:
{
make.right.equalTo(keyboardView.mas_right);
[keyView setBackgroundColor:[UIColor colorWithRed:243 green:127 blue:38 alpha:1]];
}
break;
default:
break;
}
}
}];
}
}
本例子使用的baseline去控制高度位置,这似乎不是太准,如果想要精准控制高度位置,可以使用一行一行添加的方法,每次当前行的top去equelTo上一行的bottom。 给个提示:
for(遍历所有行)
for(遍历所以列)
//当前行约束根据上一行去设置
......
- 下一个例子中,使用上面类似的方法
Masonry高级使用例子2
根据设计图,使用masonry布局:
步骤1
-(void)createUI{
UIView *titleView = [UIView new];
titleView.backgroundColor = [UIColor redColor];
UIView *caredView = [UIView new];
[self.view addSubview:caredView];
UIView *brifeView = [UIView new];
[self.view addSubview:brifeView];
//self.view
self.view.backgroundColor = [UIColor colorWithWhite:0.965 alpha:1.000];
//thrm
UIImageView *plantThrm = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"defalutPlantReferenceIcon"]];
[self.view addSubview:plantThrm];
[plantThrm mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.top.equalTo(self.view).with.offset(10);
}];
//title
[self.view addSubview:titleView];
UIImageView *bgTitleView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"bg-plant-reference-title"]];
[titleView addSubview:bgTitleView];
[titleView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view.mas_right);
make.left.equalTo(plantThrm.mas_right).with.offset(20);
make.centerY.equalTo(plantThrm.mas_centerY);
}];
[bgTitleView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(titleView);
}];
UILabel *title = [[UILabel alloc]init];
title.textColor = [UIColor whiteColor];
title.font = [UIFont fontWithName:@"Heiti SC" size:26];
title.text = _reference.name;
[titleView addSubview:title];
[title mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(titleView.mas_left).offset(10);
make.width.equalTo(titleView.mas_width);
make.centerY.equalTo(titleView.mas_centerY);
}];
//植物养护
UILabel *caredTitle = [[UILabel alloc]init];
caredTitle.textColor = [UIColor colorWithRed:0.172 green:0.171 blue:0.219 alpha:1.000];
caredTitle.font = [UIFont fontWithName:@"Heiti SC" size:10];
caredTitle.text = @"植物养护";
[self.view addSubview:caredTitle];
[caredTitle mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(plantThrm.mas_bottom).with.offset(20);
make.left.and.right.equalTo(self.view).with.offset(10);
make.height.mas_equalTo(10);
}];
//将图层的边框设置为圆脚
caredView.layer.cornerRadius = 5;
caredView.layer.masksToBounds = YES;
//给图层添加一个有色边框
caredView.layer.borderWidth = 1;
caredView.layer.borderColor = [[UIColor colorWithWhite:0.521 alpha:1.000] CGColor];
caredView.backgroundColor = [UIColor whiteColor];
[caredView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(caredTitle.mas_bottom).with.offset(5);
make.left.equalTo(self.view.mas_left).with.offset(10);
make.right.equalTo(self.view.mas_right).with.offset(-10);
make.height.equalTo(brifeView);
}];
//植物简介
UILabel *brifeTitle = [[UILabel alloc]init];
brifeTitle.textColor = [UIColor colorWithRed:0.172 green:0.171 blue:0.219 alpha:1.000];
brifeTitle.font = [UIFont fontWithName:@"Heiti SC" size:10];
brifeTitle.text = @"植物简介";
[self.view addSubview:brifeTitle];
[brifeTitle mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(caredView.mas_bottom).with.offset(20);
make.left.and.right.equalTo(self.view).with.offset(10);
make.height.mas_equalTo(10);
}];
//将图层的边框设置为圆脚
brifeView.layer.cornerRadius = 5;
brifeView.layer.masksToBounds = YES;
//给图层添加一个有色边框
brifeView.layer.borderWidth = 1;
brifeView.layer.borderColor = [[UIColor colorWithWhite:0.521 alpha:1.000] CGColor];
brifeView.backgroundColor = [UIColor whiteColor];
[brifeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(brifeTitle.mas_bottom).with.offset(5);
make.left.equalTo(self.view.mas_left).with.offset(10);
make.right.equalTo(self.view.mas_right).with.offset(-10);
make.bottom.equalTo(self.view.mas_bottom).with.offset(-10);
make.height.equalTo(caredView);
}];
}
完成之后如下图
步骤2,在上面的基础上,增加植物养护部分ui构造的代码,思想是,先构造出四行,然后根据每行单独构造出行样式。
//把块拆分为四行
-(void)createIndexUIWithView:(UIView *)view{
//拆分四行
UIView *row1 = [UIView new];
UIView *row2 = [UIView new];
UIView *row3 = [UIView new];
UIView *row4 = [UIView new];
[view addSubview:row1];
[view addSubview:row2];
[view addSubview:row3];
[view addSubview:row4];
[row1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.and.left.equalTo(view);
make.height.equalTo(view.mas_height).multipliedBy(0.25);
make.top.equalTo(view.mas_top);
}];
[row2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.and.left.equalTo(view);
make.top.equalTo(row1.mas_bottom);
make.height.equalTo(view.mas_height).multipliedBy(0.25);
}];
[row3 mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(view.mas_right);
make.top.equalTo(row2.mas_bottom);
make.height.equalTo(view.mas_height).multipliedBy(0.25);
make.left.equalTo(view.mas_left);
}];
[row4 mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.and.left.equalTo(view);
make.top.equalTo(row3.mas_bottom);
make.height.equalTo(view.mas_height).multipliedBy(0.25);
}];
[self createIndexRowUI:PlantReferenceWaterIndex withUIView:row1];
[self createIndexRowUI:PlantReferenceSumIndex withUIView:row2];
[self createIndexRowUI:PlantReferenceTemperatureIndex withUIView:row3];
[self createIndexRowUI:PlantReferenceElectrolyteIndex withUIView:row4];
}
//构造每行的UI
-(void)createIndexRowUI:(PlantReferenceIndex) index withUIView:(UIView *)view{
//index标题
UILabel *indexTitle = [UILabel new];
indexTitle.font = [UIFont fontWithName:@"HeiTi SC" size:14];
indexTitle.textColor = [UIColor colorWithWhite:0.326 alpha:1.000];
[view addSubview:indexTitle];
[indexTitle mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(view.mas_left).with.offset(20);
make.centerY.equalTo(view.mas_centerY);
}];
switch (index) {
case PlantReferenceWaterIndex:
{
indexTitle.text = @"水分";
UIImageView * current;
for(int i=1;i<=5;i++){
if(i<_reference.waterIndex){
current = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"icon_water_light"]];
}else{
current = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"icon_water_dark"]];
}
[view addSubview:current];
//间距12%,左边留空30%
[current mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(view.mas_right).with.multipliedBy(0.12*(i-1) +0.3);
make.centerY.equalTo(view.mas_centerY);
}];
}
}
break;
case PlantReferenceSumIndex:
{
indexTitle.text = @"光照";
UIImageView * current;
for(int i=1;i<=5;i++){
if(i<_reference.temperatureIndex){
current = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"icon_summer_light"]];
}else{
current = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"icon_summer_dark"]];
}
[view addSubview:current];
//间距12%,左边留空30%
[current mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(view.mas_right).with.multipliedBy(0.12*(i-1) +0.3);
make.centerY.equalTo(view.mas_centerY);
}];
}
}
break;
case PlantReferenceTemperatureIndex:
{
indexTitle.text = @"温度";
UIImageView * current;
for(int i=1;i<=5;i++){
if(i<_reference.sumIndex){
current = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"icon_temperature_light"]];
}else{
current = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"icon_temperature_dark"]];
}
[view addSubview:current];
//间距12%,左边留空30%
[current mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(view.mas_right).with.multipliedBy(0.12*(i-1) +0.3);
make.centerY.equalTo(view.mas_centerY);
}];
}
}
break;
case PlantReferenceElectrolyteIndex:
{
indexTitle.text = @"肥料";
UIImageView * current;
for(int i=1;i<=5;i++){
if(i<_reference.electrolyteIndex){
current = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"icon_electolyte_light"]];
}else{
current = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"icon_electolyte_dark"]];
}
[view addSubview:current];
//间距12%,左边留空30%
[current mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(view.mas_right).with.multipliedBy(0.12*(i-1) +0.3);
make.centerY.equalTo(view.mas_centerY);
}];
}
}
break;
default:
break;
}
}
//在步骤1createui的基础上,做了一些微调。
-(void)createUI{
self.title = _reference.name;
UIView *titleView = [UIView new];
UIView *caredView = [UIView new];
[self.view addSubview:caredView];
UITextView *brifeView = [UITextView new];
[self.view addSubview:brifeView];
//self.view
self.view.backgroundColor = [UIColor colorWithWhite:0.965 alpha:1.000];
//thrm
UIImageView *plantThrm = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"defalutPlantReferenceIcon"]];
[self.view addSubview:plantThrm];
[plantThrm mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.top.equalTo(self.view).with.offset(10);
}];
//title
[self.view addSubview:titleView];
UIImageView *bgTitleView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"bg-plant-reference-title"]];
[titleView addSubview:bgTitleView];
[titleView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view.mas_right);
make.left.equalTo(plantThrm.mas_right).with.offset(20);
make.centerY.equalTo(plantThrm.mas_centerY);
}];
[bgTitleView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(titleView);
}];
UILabel *title = [[UILabel alloc]init];
title.textColor = [UIColor whiteColor];
title.font = [UIFont fontWithName:@"Heiti SC" size:26];
title.text = _reference.name;
[titleView addSubview:title];
[title mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(titleView.mas_left).offset(10);
make.width.equalTo(titleView.mas_width);
make.centerY.equalTo(titleView.mas_centerY);
}];
//植物养护
UILabel *caredTitle = [[UILabel alloc]init];
caredTitle.textColor = [UIColor colorWithRed:0.172 green:0.171 blue:0.219 alpha:1.000];
caredTitle.font = [UIFont fontWithName:@"Heiti SC" size:10];
caredTitle.text = @"植物养护";
[self.view addSubview:caredTitle];
[caredTitle mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(plantThrm.mas_bottom).with.offset(20);
make.left.and.right.equalTo(self.view).with.offset(10);
make.height.mas_equalTo(10);
}];
//植物养护 数据
[self createIndexUIWithView:caredView];
//将图层的边框设置为圆脚
caredView.layer.cornerRadius = 5;
caredView.layer.masksToBounds = YES;
//给图层添加一个有色边框
caredView.layer.borderWidth = 1;
caredView.layer.borderColor = [[UIColor colorWithWhite:0.521 alpha:1.000] CGColor];
caredView.backgroundColor = [UIColor whiteColor];
[caredView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(caredTitle.mas_bottom).with.offset(5);
make.left.equalTo(self.view.mas_left).with.offset(10);
make.right.equalTo(self.view.mas_right).with.offset(-10);
make.height.equalTo(brifeView);
}];
//植物简介
UILabel *brifeTitle = [[UILabel alloc]init];
brifeTitle.textColor = [UIColor colorWithRed:0.172 green:0.171 blue:0.219 alpha:1.000];
brifeTitle.font = [UIFont fontWithName:@"Heiti SC" size:10];
brifeTitle.text = @"植物简介";
[self.view addSubview:brifeTitle];
[brifeTitle mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(caredView.mas_bottom).with.offset(20);
make.left.and.right.equalTo(self.view).with.offset(10);
make.height.mas_equalTo(10);
}];
//将图层的边框设置为圆脚
brifeView.layer.cornerRadius = 5;
brifeView.layer.masksToBounds = YES;
//给图层添加一个有色边框
brifeView.layer.borderWidth = 1;
brifeView.layer.borderColor = [[UIColor colorWithWhite:0.447 alpha:1.000] CGColor];
brifeView.backgroundColor = [UIColor whiteColor];
//文字样式
// brifeView.textColor = [UIColor colorWithWhite:0.352 alpha:1.000];
// brifeView.font = [UIFont fontWithName:@"HeiTi SC" size:12];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
paragraphStyle.lineHeightMultiple = 20.f;
paragraphStyle.maximumLineHeight = 25.f;
paragraphStyle.minimumLineHeight = 15.f;
paragraphStyle.alignment = NSTextAlignmentJustified;
NSDictionary *attributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:12], NSParagraphStyleAttributeName:paragraphStyle, NSForegroundColorAttributeName:[UIColor colorWithWhite:0.447 alpha:1.000]};
//植物简介数据
//brifeView.text = _reference.brief;
brifeView.attributedText = [[NSAttributedString alloc] initWithString: _reference.brief attributes:attributes];
[brifeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(brifeTitle.mas_bottom).with.offset(5);
make.left.equalTo(self.view.mas_left).with.offset(10);
make.right.equalTo(self.view.mas_right).with.offset(-10);
make.bottom.equalTo(self.view.mas_bottom).with.offset(-10);
make.height.equalTo(caredView);
}];
}
}
采坑: 一个UIScrollView 上add 一些view
view 布局用masonry,
如下, 高度 和底部 有一个算多余约束 无报错, 但是UIScrollView, contentOffset 页面已跳转就会变为0,0
self.hotVideoListTab.mas_makeConstraints { (make) in
make?.left.mas_equalTo()(self.scrollView)
make?.top.mas_equalTo()(self.scrollView)
// make?.bottom.mas_equalTo()(self.scrollView)
make?.height.mas_equalTo()(self.scrollView)
make?.width.mas_equalTo()(stageWidth)
}
文章评论