iOS:Masonry 英文原档介绍
Masonry 英文原档介绍:
Masonry is still actively maintained, we are committed to fixing bugs and merging good quality PRs from the wider community. However if you're using Swift in your project, we recommend using SnapKit as it provides better type safety with a simpler API.
Masonry is a light-weight layout framework which wraps AutoLayout with a nicer syntax. Masonry has its own layout DSL which provides a chainable way of describing your NSLayoutConstraints which results in layout code that is more concise and readable. Masonry supports iOS and Mac OS X.
For examples take a look at the Masonry iOS Examples project in the Masonry workspace. You will need to run pod install after downloading.
What's wrong with NSLayoutConstraints?
Under the hood Auto Layout is a powerful and flexible way of organising and laying out your views. However creating constraints from code is verbose and not very descriptive. Imagine a simple example in which you want to have a view fill its superview but inset by 10 pixels on every side
UIView *superview = self;
UIView *view1 = [[UIView alloc] init];
view1.translatesAutoresizingMaskIntoConstraints = NO;
view1.backgroundColor = [UIColor greenColor];
[superview addSubview:view1]; UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10); [superview addConstraints:@[ //view1 constraints
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:padding.top], [NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:padding.left], [NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-padding.bottom], [NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeRight
multiplier:1
constant:-padding.right], ]];
Even with such a simple example the code needed is quite verbose and quickly becomes unreadable when you have more than 2 or 3 views. Another option is to use Visual Format Language (VFL), which is a bit less long winded. However the ASCII type syntax has its own pitfalls and its also a bit harder to animate as NSLayoutConstraint constraintsWithVisualFormat: returns an array.
Prepare to meet your Maker!
Heres the same constraints created using MASConstraintMaker
UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
make.left.equalTo(superview.mas_left).with.offset(padding.left);
make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];
Or even shorter
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(superview).with.insets(padding);
}];
Also note in the first example we had to add the constraints to the superview [superview addConstraints:.... Masonry however will automagically add constraints to the appropriate view.
Masonry will also call view1.translatesAutoresizingMaskIntoConstraints = NO; for you.
Not all things are created equal
.equalToequivalent to NSLayoutRelationEqual
.lessThanOrEqualToequivalent to NSLayoutRelationLessThanOrEqual
.greaterThanOrEqualToequivalent to NSLayoutRelationGreaterThanOrEqual
These three equality constraints accept one argument which can be any of the following:
1. MASViewAttribute
make.centerX.lessThanOrEqualTo(view2.mas_left);
| MASViewAttribute | NSLayoutAttribute |
|---|---|
| view.mas_left | NSLayoutAttributeLeft |
| view.mas_right | NSLayoutAttributeRight |
| view.mas_top | NSLayoutAttributeTop |
| view.mas_bottom | NSLayoutAttributeBottom |
| view.mas_leading | NSLayoutAttributeLeading |
| view.mas_trailing | NSLayoutAttributeTrailing |
| view.mas_width | NSLayoutAttributeWidth |
| view.mas_height | NSLayoutAttributeHeight |
| view.mas_centerX | NSLayoutAttributeCenterX |
| view.mas_centerY | NSLayoutAttributeCenterY |
| view.mas_baseline | NSLayoutAttributeBaseline |
2. UIView/NSView
if you want view.left to be greater than or equal to label.left :
//these two constraints are exactly the same
make.left.greaterThanOrEqualTo(label);
make.left.greaterThanOrEqualTo(label.mas_left);
3. NSNumber
Auto Layout allows width and height to be set to constant values. if you want to set view to have a minimum and maximum width you could pass a number to the equality blocks:
//width >= 200 && width <= 400
make.width.greaterThanOrEqualTo(@200);
make.width.lessThanOrEqualTo(@400)
However Auto Layout does not allow alignment attributes such as left, right, centerY etc to be set to constant values. So if you pass a NSNumber for these attributes Masonry will turn these into constraints relative to the view’s superview ie:
//creates view.left = view.superview.left + 10
make.left.lessThanOrEqualTo(@10)
Instead of using NSNumber, you can use primitives and structs to build your constraints, like so:
make.top.mas_equalTo(42);
make.height.mas_equalTo(20);
make.size.mas_equalTo(CGSizeMake(50, 100));
make.edges.mas_equalTo(UIEdgeInsetsMake(10, 0, 10, 0));
make.left.mas_equalTo(view).mas_offset(UIEdgeInsetsMake(10, 0, 10, 0));
By default, macros which support autoboxing are prefixed with mas_. Unprefixed versions are available by defining MAS_SHORTHAND_GLOBALS before importing Masonry.
4. NSArray
An array of a mixture of any of the previous types
make.height.equalTo(@[view1.mas_height, view2.mas_height]);
make.height.equalTo(@[view1, view2]);
make.left.equalTo(@[view1, @100, view3.right]);
Learn to prioritize
.priorityallows you to specify an exact priority
.priorityHighequivalent to UILayoutPriorityDefaultHigh
.priorityMediumis half way between high and low
.priorityLowequivalent to UILayoutPriorityDefaultLow
Priorities are can be tacked on to the end of a constraint chain like so:
make.left.greaterThanOrEqualTo(label.mas_left).with.priorityLow(); make.top.equalTo(label.mas_top).with.priority(600);
Composition, composition, composition
Masonry also gives you a few convenience methods which create multiple constraints at the same time. These are called MASCompositeConstraints
edges
// make top, left, bottom, right equal view2
make.edges.equalTo(view2); // make top = superview.top + 5, left = superview.left + 10,
// bottom = superview.bottom - 15, right = superview.right - 20
make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20))
size
// make width and height greater than or equal to titleLabel
make.size.greaterThanOrEqualTo(titleLabel) // make width = superview.width + 100, height = superview.height - 50
make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50))
center
// make centerX and centerY = button1
make.center.equalTo(button1) // make centerX = superview.centerX - 5, centerY = superview.centerY + 10
make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10))
You can chain view attributes for increased readability:
// All edges but the top should equal those of the superview
make.left.right.and.bottom.equalTo(superview);
make.top.equalTo(otherView);
Hold on for dear life
Sometimes you need modify existing constraints in order to animate or remove/replace constraints. In Masonry there are a few different approaches to updating constraints.
1. References
You can hold on to a reference of a particular constraint by assigning the result of a constraint make expression to a local variable or a class property. You could also reference multiple constraints by storing them away in an array.
// in public/private interface
@property (nonatomic, strong) MASConstraint *topConstraint; ... // when making constraints
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
self.topConstraint = make.top.equalTo(superview.mas_top).with.offset(padding.top);
make.left.equalTo(superview.mas_left).with.offset(padding.left);
}]; ...
// then later you can call
[self.topConstraint uninstall];
2. mas_updateConstraints
Alternatively if you are only updating the constant value of the constraint you can use the convience method mas_updateConstraints instead of mas_makeConstraints
// this is Apple's recommended place for adding/updating constraints
// this method can get called multiple times in response to setNeedsUpdateConstraints
// which can be called by UIKit internally or in your code if you need to trigger an update to your constraints
- (void)updateConstraints {
[self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
make.width.equalTo(@(self.buttonSize.width)).priorityLow();
make.height.equalTo(@(self.buttonSize.height)).priorityLow();
make.width.lessThanOrEqualTo(self);
make.height.lessThanOrEqualTo(self);
}]; //according to apple super should be called at end of method
[super updateConstraints];
}
3. mas_remakeConstraints
mas_updateConstraints is useful for updating a set of constraints, but doing anything beyond updating constant values can get exhausting. That's where mas_remakeConstraints comes in.
mas_remakeConstraints is similar to mas_updateConstraints, but instead of updating constant values, it will remove all of its contraints before installing them again. This lets you provide different constraints without having to keep around references to ones which you want to remove.
- (void)changeButtonPosition {
[self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
make.size.equalTo(self.buttonSize);
if (topLeft) {
make.top.and.left.offset(10);
} else {
make.bottom.and.right.offset(-10);
}
}];
}
You can find more detailed examples of all three approaches in the Masonry iOS Examples project.
When the ^&*!@ hits the fan!
Laying out your views doesn't always goto plan. So when things literally go pear shaped, you don't want to be looking at console output like this:
Unable to simultaneously satisfy constraints.....blah blah blah....
(
"<NSLayoutConstraint:0x7189ac0 V:[UILabel:0x7186980(>=5000)]>",
"<NSAutoresizingMaskLayoutConstraint:0x839ea20 h=--& v=--& V:[MASExampleDebuggingView:0x7186560(416)]>",
"<NSLayoutConstraint:0x7189c70 UILabel:0x7186980.bottom == MASExampleDebuggingView:0x7186560.bottom - 10>",
"<NSLayoutConstraint:0x7189560 V:|-(1)-[UILabel:0x7186980] (Names: '|':MASExampleDebuggingView:0x7186560 )>"
) Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7189ac0 V:[UILabel:0x7186980(>=5000)]>
Masonry adds a category to NSLayoutConstraint which overrides the default implementation of - (NSString *)description. Now you can give meaningful names to views and constraints, and also easily pick out the constraints created by Masonry.
which means your console output can now look like this:
Unable to simultaneously satisfy constraints......blah blah blah....
(
"<NSAutoresizingMaskLayoutConstraint:0x8887740 MASExampleDebuggingView:superview.height == 416>",
"<MASLayoutConstraint:ConstantConstraint UILabel:messageLabel.height >= 5000>",
"<MASLayoutConstraint:BottomConstraint UILabel:messageLabel.bottom == MASExampleDebuggingView:superview.bottom - 10>",
"<MASLayoutConstraint:ConflictingConstraint[0] UILabel:messageLabel.top == MASExampleDebuggingView:superview.top + 1>"
) Will attempt to recover by breaking constraint
<MASLayoutConstraint:ConstantConstraint UILabel:messageLabel.height >= 5000>
For an example of how to set this up take a look at the Masonry iOS Examples project in the Masonry workspace.
Installation
In your Podfile
pod 'Masonry'
If you want to use masonry without all those pesky 'mas_' prefixes. Add #define MAS_SHORTHAND to your prefix.pch before importing Masonry
#define MAS_SHORTHAND
Get busy Masoning
#import "Masonry.h"
Code Snippets
Copy the included code snippets to ~/Library/Developer/Xcode/UserData/CodeSnippets to write your masonry blocks at lightning speed!
mas_make -> [<view> mas_makeConstraints:^(MASConstraintMaker *make){<code>}];
mas_update -> [<view> mas_updateConstraints:^(MASConstraintMaker *make){<code>}];
mas_remake -> [<view> mas_remakeConstraints:^(MASConstraintMaker *make){<code>}];
Features
- Not limited to subset of Auto Layout. Anything NSLayoutConstraint can do, Masonry can do too!
- Great debug support, give your views and constraints meaningful names.
- Constraints read like sentences.
- No crazy macro magic. Masonry won't pollute the global namespace with macros.
- Not string or dictionary based and hence you get compile time checking.
TODO
- Eye candy
- Mac example project
- More tests and examples
iOS:Masonry 英文原档介绍的更多相关文章
- iOS:Masonry介绍与使用
Masonry介绍与使用实践:快速上手Autolayout frame----->autoresing------->autoLayout-------->sizeClasses ...
- iOS 9应用开发教程之创建iOS 9项目与模拟器介绍
iOS 9应用开发教程之创建iOS 9项目与模拟器介绍 编写第一个iOS 9应用 本节将以一个iOS 9应用程序为例,为开发者讲解如何使用Xcode 7.0去创建项目,以及iOS模拟器的一些功能.编辑 ...
- (译)IOS block编程指南 1 介绍
Introduction(介绍) Block objects are a C-level syntactic and runtime feature. They are similar to stan ...
- iOS开发网络篇—简单介绍ASI框架的使用
iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大 ...
- iOS开发UI篇—简单介绍静态单元格的使用
iOS开发UI篇—简单介绍静态单元格的使用 一.实现效果与说明 说明:观察上面的展示效果,可以发现整个界面是由一个tableview来展示的,上面的数据都是固定的,且几乎不会改变. 要完成上面的效果, ...
- iOS开发多线程篇—GCD介绍
iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 G ...
- iOS开发官方文档汇总
程序员的学习过程是无止境的,程序员学习的途径是多样的.可以从视频教程中领悟,也可以从他人的代码中 理解.但当我们专注于某一个平台在开发的时候,对于某个API使用或者功能实现有疑问,通常简单的测试可以让 ...
- iOS开发Swift篇—简单介绍
iOS开发Swift篇—简单介绍 一.简介 Swift是苹果于2014年WWDC(苹果开发者大会)发布的全新编程语言 Swift在天朝译为“雨燕”,是它的LOGO 是一只燕子,跟Objective-C ...
- spring-data-solr官方学习文档介绍
spring-data-solr文档介绍如下: 通过http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd(spring ...
随机推荐
- 第一个java的小东西
第一次自己写的一个java的小东西,毕竟自己第一次写的,其中可谓是历经艰难,最后总结下来就是java实在是不适合写界面化的东西代码量比较大,这还不是最关键的,最关键的是控件的位置实在是太难控制了. 这 ...
- js事件中绑定另一事件导致事件多次执行
1.html代码 <input type="button" value="add"> <input type="button&quo ...
- linux下面which whereis find locate的使用
我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索.这些是从网上找到的资料,因为有时很长时间不会用到,当要用的时候经常弄混了,所以放到这里方便使用. which ...
- linux shell 脚本实现tcp/upd协议通讯(重定向应用)
linux shell 脚本实现tcp/upd协议通讯(重定向应用) http://www.cnblogs.com/chengmo/archive/2010/10/22/1858302.html
- 使用Github官方提供的gitignore过滤Git提交的文件
https://github.com/github/gitignore 在Gitignore项目主页找到VisualStudio.gitignore 下载后放到自己项目根目录的.vs文件夹提交就可以在 ...
- AWS Ubuntu部署EMQTT的小坑
Redis身份认证中的 is_superuser 表示不查检用户密码和ACL规则 如果是Ubuntu,集群设置节点名须改为:ubuntu@私有Ip,安全组最好相互开放所有端口 如果使用了ELB,EMQ ...
- 搜索引擎--范例:django之初试牛刀
这学期学了一门课<信息检索>,也就是传说中的搜索引擎 大作业自然而然的让我们自己做一个小型的搜索引擎.于是乎,我们本次的主题就诞生了 我也是边学边用,下面和大家一起分享我在这个过程中学到的 ...
- C# 对话框使用大全
对话框中我们常用了以下几种:1.文件对话框(FileDialog) 它又常用到两个: 打开文件对话框(OpenFileDialog) 保存文件对话(SaveFileDialog)2.字体对话框(Fon ...
- Python 读写 Excel(转)
Python 读写 Excel 基本上, 这个网页已经说明一切了: http://pypi.python.org/pypi/xlrd 等有时间再把这个页面写漂亮,现在先记一些代码. 读Excel 先建 ...
- HDU 1427 速算24点【数值型DFS】
速算24点 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...