# Masonry [](https://travis-ci.org/SnapKit/Masonry) [](https://coveralls.io/r/SnapKit/Masonry) [](https://github.com/Carthage/Carthage) 
**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](https://github.com/SnapKit/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
```obj-c
UIView *superview = self.view;
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
```obj-c
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
```obj-c
[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
> `.equalTo` equivalent to **NSLayoutRelationEqual**
> `.lessThanOrEqualTo` equivalent to **NSLayoutRelationLessThanOrEqual**
> `.greaterThanOrEqualTo` equivalent to **NSLayoutRelationGreaterThanOrEqual**
These three equality constraints accept one argument which can be any of the following:
#### 1. MASViewAttribute
```obj-c
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 :
```obj-c
//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:
```obj-c
//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:
```obj-c
//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:
```obj-c
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](https://en.wikipedia.org/wiki/Autoboxing#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
```obj-c
make.height.equalTo(@[view1.mas_height, view2.mas_height]);
make.height.equalTo(@[view1, view2]);
make.left.equalTo(@[view1, @100, view3.right]);
````
## Learn to prioritize
> `.priority` allows you to specify an exact priority
> `.priorityHigh` equivalent to **UILayoutPriorityDefaultHigh**
> `.priorityMedium` is half way between high and low
> `.priorityLow` equivalent to **UILayoutPriorityDefaultLow**
Priorities are can be tacked on to the end of a constraint chain like so:
```obj-c
make.left.greaterThanO
OC-Json转模型Array(Plist嵌套模型)
需积分: 0 154 浏览量
更新于2023-07-05
收藏 448KB ZIP 举报
在iOS开发中,数据交换和存储经常涉及到JSON和Plist格式。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于网络API的数据传输,而Plist(Property List)是苹果系统中的数据存储格式,常用于配置文件或者简单的数据持久化。本篇文章将深入探讨如何在Objective-C(OC)中将接收到的JSON数据转换为模型数组,特别是在处理Plist嵌套模型的情况下。
我们需要理解JSON和Plist之间的基本差异。JSON是一种基于文本的、易于人阅读和编写的数据格式,同时也很容易让机器解析和生成。它由键值对组成,支持数组和对象两种数据结构。Plist则是苹果特有的二进制或XML格式,用来存储基础数据类型如字符串、数字、日期、布尔值、数组和字典。
在OC中,我们通常使用NSJSONSerialization类来解析和序列化JSON数据。例如,当接收到一个JSON字符串时,可以使用`dataWithJSONObject:`方法将其转换为NSData对象,然后用`JSONObjectWithData:options:error:`方法反序列化为Foundation对象,如NSArray或NSDictionary。
对于Plist,我们可以使用`propertyListWithData:options:format:error:`或`dictionaryWithContentsOfFile:`等方法读取和解析Plist文件。然而,当Plist中存在嵌套的模型时,我们需要自定义模型类来映射JSON或Plist的结构。
在处理嵌套模型时,每个模型类都需要遵循`NSCoding`协议,提供`encodeWithCoder:`和`initWithCoder:`方法,以便进行序列化和反序列化。对于JSON到模型的转换,可以使用第三方库如Mantle或 ObjectMapper,它们提供了便利的方法将JSON字典自动映射到自定义模型对象。
以下是一个简单的示例,展示如何实现JSON到模型数组的转换:
1. 定义一个模型类,比如`User`,并实现`NSCoding`协议:
```objc
@interface User : NSObject <NSCoding>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSArray *friends; // 假设这是嵌套的Plist模型
// ... 其他属性和初始化方法
@end
@implementation User
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.friends forKey:@"friends"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
self.name = [aDecoder decodeObjectOfClass:NSString.class forKey:@"name"];
self.friends = [aDecoder decodeObjectOfClass:[NSArray class] forKey:@"friends"];
}
return self;
}
@end
```
2. 解析JSON数据:
```objc
NSData *jsonData = [NSData dataWithContentsOfURL:url]; // 假设url指向的是JSON数据
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
if (error) {
NSLog(@"Error parsing JSON: %@", error);
} else {
NSArray *usersDicts = jsonDict[@"users"];
NSMutableArray *users = [NSMutableArray array];
for (NSDictionary *userDict in usersDicts) {
User *user = [[User alloc] initWithDictionary:userDict];
[users addObject:user];
}
// 现在users数组包含了从JSON转换过来的User模型对象
}
```
3. 如果`friends`字段是嵌套的Plist模型,你还需要为`Friend`类做同样的编码和解码操作,并在`User`类的`initWithDictionary:`方法中正确地处理这个嵌套数组。
在实际项目中,可能需要处理更复杂的嵌套模型,包括字典、数组和自定义模型的混合结构。通过自定义模型类和利用`NSCoding`协议,我们可以方便地将JSON或Plist数据转换为可操作的对象,使得数据处理更加直观和高效。同时,选择合适的第三方库也能简化这个过程,提高开发效率。

冯汉栩
- 粉丝: 541
最新资源
- 基于计算机视觉的小车目标检测与动态跟踪技术研究 (注:共 16 字,核心动作 “检测”“跟踪” 及对象 “小车” 均保留,通过 “基于计算机视觉”“动态”“技术研究” 补充表述维度,确保原意不变且满足
- 基于船舶的目标检测技术研究项目
- MATLAB中基于YALMIP的微电网优化调度模型:含蓄电池与市场购售电约束的总费用最小化 · 微电网
- 基于船舶目标开展精准识别与检测的技术项目
- 多相流相对渗透率计算中相场与水平集方法的质量守恒策略实现
- 基于DSP28035的60KW三相光伏并网逆变器IGBT驱动电路设计与优化 开关损耗优化
- 三相PWM整流器并联仿真及零序环流抑制算法的研究与应用
- 触摸屏直接控制变频器:昆仑通泰TPC与安川V1000及其他品牌变频器的485端口通信实现 宝典
- 多供区交直流潮流模型构建与求解:基于改进IEEE39节点系统的柔性互联算法研究 实战版
- 基于 OpenCV 原生库实现目标检测与文本检测的方法
- 基于C代码的异步电机矢量控制算法仿真与双闭环解耦控制实现高精度转速调节
- 本仓库存有目标检测 YOLO 系列及改进模块代码,欢迎自取
- Matlab Simulink中基于MRAS的直流母线电压传感器容错控制方法研究:包括设置电压传感器断路与漂移故障,并利用冗余开关进行容错切换
- 基于Verilog的UART IP核心开发与FPGA移植:从编码到仿真的全流程解析
- 风光柴储混合微电网中储能电池系统的MATLAB仿真研究:实现互补能量管理
- 汇川通IT7000触摸屏标准模板程序解析:提升编程效率与稳定性的关键