iOS_autoLayout_Masonry
概述
Masonry是一個(gè)輕量級(jí)的布局框架與更好的包裝AutoLayout語(yǔ)法。
Masonry有它自己的布局方式,描述NSLayoutConstraints使布局代碼更簡(jiǎn)潔易讀。
Masonry支持iOS和Mac OS X。
Masonry github 地址:https://github.com/SnapKit/Masonry
目
錄
對(duì)比? ? NSLayoutConstraints vs Masonry
示例? ? 13個(gè)Masonry示例(用代碼來(lái)說(shuō)話)
對(duì)比
使用NSLayoutConstraints創(chuàng)建約束
@interface contrastViewController()
@property (nonatomic,strong) UIView *myView;
@end
@implementation contrastViewController
-(void)loadView
{
[super loadView];
_myView = [[UIView alloc]init];
[self.view addSubview:_myView];
}
-(void)viewDidLoad
{
[super viewDidLoad];
_myView.backgroundColor = [UIColor orangeColor];
_myView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraints:@[
[NSLayoutConstraint constraintWithItem:_myView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:10],
[NSLayoutConstraint constraintWithItem:_myView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:10],
[NSLayoutConstraint constraintWithItem:_myView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-10],
[NSLayoutConstraint constraintWithItem:_myView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeRight
multiplier:1
constant:-10],
]];
}
@end
即使這樣一個(gè)簡(jiǎn)單的示例,所需的代碼量也要非常冗長(zhǎng);
另一個(gè)選擇是使用視圖形式語(yǔ)言(VFL),這個(gè)少一點(diǎn)啰嗦;然而ASCLL類型語(yǔ)法有其自身的缺陷,也有些約束難以實(shí)現(xiàn);
使用Masonry創(chuàng)建相同的約束
@interface contrastViewController()
@property (nonatomic,strong) UIView *myView;
@end
@implementation contrastViewController
-(void)loadView
{
[super loadView];
_myView = [[UIView alloc]init];
[self.view addSubview:_myView];
}
-(void)viewDidLoad
{
[super viewDidLoad];
_myView.backgroundColor = [UIColor orangeColor];
[_myView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(10);? ? //? 相對(duì)于self.view 頂部 10
make.left.equalTo(self.view).offset(10);? ? //? 相對(duì)于self.view 左邊 10
make.bottom.equalTo(self.view).offset(-10); //? 相對(duì)于self.view 底部 -10
make.right.equalTo(self.view).offset(-10);? //? 相對(duì)于self.view 右邊 -10
}];
}
@end
還可以更簡(jiǎn)潔
@interface contrastViewController()
@property (nonatomic,strong) UIView *myView;
@end
@implementation contrastViewController
-(void)loadView
{
[super loadView];
_myView = [[UIView alloc]init];
[self.view addSubview:_myView];
}
-(void)viewDidLoad
{
[super viewDidLoad];
_myView.backgroundColor = [UIColor orangeColor];
UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
[_myView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).insets(padding);
}];
}
@end
還要注意在第一個(gè)例子中我們必須添加約束到self.view,_myView.translatesAutoresizingMaskIntoConstraints = NO;
然而Masonry將自動(dòng)添加約束到適當(dāng)?shù)囊晥D_myView.translatesAutoresizingMaskIntoConstraints = NO;
示例
示例 00
@interface _00_BasicViewController ()
@property (nonatomic) UIView *greenView;
@end
@implementation _00_BasicViewController
-(void)loadView
{
[super loadView];
_greenView = [[UIView alloc]init];
[self.view addSubview:_greenView];
}
- (void)viewDidLoad {
[super viewDidLoad];
_greenView.backgroundColor = [UIColor greenColor];
[_greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(200, 200));? ? // 設(shè)置大小
make.center.equalTo(self.view);? ? ? ? ? ? ? ? // 居中顯示
}];
}
@end
示例01
@interface _01_BasicViewController ()
@property (nonatomic,strong) UIView *greenView;
@property (nonatomic,strong) UIView *redView;
@property (nonatomic,strong) UIView *blueView;
@end
@implementation _01_BasicViewController
-(void)loadView
{
[super loadView];
_greenView = [[UIView? alloc]init];
_redView? = [[UIView alloc]init];
_blueView? = [[UIView alloc]init];
[self.view addSubview:_greenView];
[self.view addSubview:_redView];
[self.view addSubview:_blueView];
}
- (void)viewDidLoad {
[super viewDidLoad];
[_greenView setBackgroundColor:[UIColor greenColor]];
[_redView? setBackgroundColor:[UIColor redColor]];
[_blueView? setBackgroundColor:[UIColor blueColor]];
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(10);? ? ? ? ? ? ? ? ? // 頂 等于 View 頂 +10
make.left.equalTo(self.view).offset(10);? ? ? ? ? ? ? ? // 左 等于 View 左 +10
make.bottom.equalTo(_blueView.mas_top).offset(-10);? ? ? // 底 等于 藍(lán)色? 頂 -10
make.right.equalTo(_redView.mas_left).offset(-10);? ? ? // 右 等于 紅色? 右 -10
make.width.equalTo(_redView);? ? ? ? ? ? ? ? ? ? ? ? ? ? // 寬 等于 紅色? 寬
make.height.equalTo(_redView);? ? ? ? ? ? ? ? ? ? ? ? ? // 高 等于 紅色? 高
make.height.equalTo(_blueView);? ? ? ? ? ? ? ? ? ? ? ? ? // 高 等于 藍(lán)色? 高
}];
[self.redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_greenView);? ? ? ? ? ? ? ? ? ? ? ? ? ? // 頂 等于 綠色? 頂
make.left.equalTo(_greenView.mas_right).offset(10);? ? ? // 左 等于 綠色? 右 +10
make.bottom.equalTo(_greenView);? ? ? ? ? ? ? ? ? ? ? ? // 底 等于 綠色? 底
make.right.equalTo(self.view).offset(-10);? ? ? ? ? ? ? // 右 等于 View? 右 -10
make.width.equalTo(_greenView);? ? ? ? ? ? ? ? ? ? ? ? ? // 寬 等于 綠色? 寬
make.height.equalTo(_greenView);? ? ? ? ? ? ? ? ? ? ? ? // 高 等于 綠色? 高
}];
[self.blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_greenView.mas_bottom).offset(10);? ? ? // 頂 等于 綠色? 底 +10
make.left.equalTo(self.view).offset(10);? ? ? ? ? ? ? ? // 左 等于 View? 左 +10
make.bottom.equalTo(self.view).offset(-10);? ? ? ? ? ? ? // 底 等于 View? 底 -10
make.right.equalTo(self.view).offset(-10);? ? ? ? ? ? ? // 右 等于 View? 右 -10
make.height.equalTo(_greenView);? ? ? ? ? ? ? ? ? ? ? ? // 高 等于 綠色? 高
}];
}
@end
示例02
@interface _02_Update_ConstraintsViewController ()
@property (nonatomic,strong) UIButton *button;
@property (nonatomic,assign) CGSize buttonSize;
@end
@implementation _02_Update_ConstraintsViewController
-(void)loadView
{
[super loadView];
_button = [UIButton buttonWithType:UIButtonTypeSystem];
[self.view addSubview:_button];
}
- (void)viewDidLoad {
[super viewDidLoad];
[_button setTitle:@"點(diǎn)擊" forState:UIControlStateNormal];
[_button.layer setBorderColor:[[UIColor greenColor] CGColor]];
[_button.layer setBorderWidth:3];
[_button addTarget:self action:@selector(clickWithButton:) forControlEvents:UIControlEventTouchUpInside];
_buttonSize = CGSizeMake(100, 100);
[self.view setNeedsUpdateConstraints];
}
- (void)updateViewConstraints {
[self.button mas_updateConstraints:^(MASConstraintMaker *make) {// 更新約束
make.center.equalTo(self.view); // 居中
make.width.equalTo(@(_buttonSize.width)).priorityLow();? ? // 寬 等于 100 優(yōu)先級(jí) 低 第一次顯示的時(shí)候是100
make.height.equalTo(@(_buttonSize.height)).priorityLow();? // 高 等于 100 優(yōu)先級(jí) 低 第一次顯示的時(shí)候是100
make.width.lessThanOrEqualTo(self.view);? ? ? ? ? ? ? ? ? ? // 寬 小于 等于 view? 當(dāng)寬度大于等于 view 需滿足此條件
make.height.lessThanOrEqualTo(self.view);? ? ? ? ? ? ? ? ? // 高 小于 等于 view? 當(dāng)高度大于等于 view 需滿足此條件
}];
[super updateViewConstraints];
}
- (void)clickWithButton:(UIButton *)button
{
_buttonSize = CGSizeMake(_buttonSize.width * 1.3, _buttonSize.height * 1.3); // 寬高 乘 1.3
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:0.4 animations:^{
[self.view layoutIfNeeded];
}];
}
@end
示例03
@interface _03_Remake_ConstraintsViewController ()
@property (nonatomic, strong) UIButton *movingButton;
@property (nonatomic, assign) BOOL topLeft;
@end
@implementation _03_Remake_ConstraintsViewController
-(void)loadView
{
[super loadView];
_movingButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.view addSubview:_movingButton];
}
- (void)viewDidLoad {
[super viewDidLoad];
[_movingButton setTitle:@"點(diǎn)擊" forState:UIControlStateNormal];
_movingButton.layer.borderColor = UIColor.greenColor.CGColor;
_movingButton.layer.borderWidth = 3;
[_movingButton addTarget:self action:@selector(clickWithButton:) forControlEvents:UIControlEventTouchUpInside];
self.topLeft = YES;
[self.view setNeedsUpdateConstraints];
}
+ (BOOL)requiresConstraintBasedLayout
{
return YES;
}
- (void)updateViewConstraints {
//? 重置約束 會(huì)把已有的約束刪除重新添加
[self.movingButton mas_remakeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@(100));
make.height.equalTo(@(100));
if (self.topLeft) {
make.left.equalTo(self.view).offset(10);
make.top.equalTo(self.view).offset(10);
}
else {
make.bottom.equalTo(self.view).offset(-10);
make.right.equalTo(self.view).offset(-10);
}
}];
[super updateViewConstraints];
}
- (void)clickWithButton:(UIButton *)button
{
self.topLeft = !self.topLeft;
[self.view setNeedsUpdateConstraints];
[self.view updateConstraintsIfNeeded];
[UIView animateWithDuration:0.4 animations:^{
[self.view layoutIfNeeded];
}];
}
@end
示例04
@interface _04_Using_ConstantsViewController ()
@property (nonatomic,strong) UIView *purpleView;
@property (nonatomic,strong) UIView *orangeView;
@end
@implementation _04_Using_ConstantsViewController
-(void)loadView
{
[super loadView];
self.purpleView = [[UIView alloc]init];
self.orangeView = [[UIView alloc]init];
[self.view addSubview:_purpleView];
[self.view addSubview:_orangeView];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.purpleView.backgroundColor = UIColor.purpleColor;
self.orangeView.backgroundColor = UIColor.orangeColor;
[self.purpleView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@20);? ? ? // 頂 20 相對(duì)于self.View
make.left.equalTo(@20);? ? // 左 20
make.bottom.equalTo(@-20);? // 底 -20
make.right.equalTo(@-20);? // 右 -20
}];
[self.orangeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(CGPointMake(0, 50)); // 中心點(diǎn)Y 相對(duì)于self.View Y 50
make.size.mas_equalTo(CGSizeMake(200, 100)); // 大小 200 100
}];
}
@end
示例05
@interface _05_Composite_EdgesViewController ()
@end
@implementation _05_Composite_EdgesViewController
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIView *lastView = self.view;
for (int i = 0; i < 10; i++) {
UIView *view = [[UIView alloc]init];
view.backgroundColor = [self randomColor];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(lastView).insets(UIEdgeInsetsMake(5, 10, 15, 20));//相對(duì)于上一個(gè)View 5 10 -15 -20
}];
lastView = view;
}
}
- (UIColor *)randomColor {
CGFloat hue = ( arc4random() % 256 / 256.0 );? //? 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5;? //? 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5;? //? 0.5 to 1.0, away from black
return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
}
@end
示例06
@interface _06_Aspect_FitViewController ()
@property (nonatomic,strong) UIView *topView;
@property (nonatomic,strong) UIView *topInnerView;
@property (nonatomic,strong) UIView *bottomView;
@property (nonatomic,strong) UIView *bottomInnerView;
@end
@implementation _06_Aspect_FitViewController
-(void)loadView
{
[super loadView];
self.topView? ? ? ? ? ? = [[UIView alloc] init];
self.topInnerView? ? ? = [[UIView alloc] init];
self.bottomView? ? ? ? = [[UIView alloc] init];
self.bottomInnerView? ? = [[UIView alloc] init];
[self.view addSubview:_topView];
[self.view addSubview:_topInnerView];
[self.view addSubview:_bottomView];
[self.view addSubview:_bottomInnerView];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.topView.backgroundColor? ? ? ? ? ? = [UIColor redColor];
self.bottomView.backgroundColor? ? ? ? = [UIColor blueColor];
self.topInnerView.backgroundColor? ? ? = [UIColor greenColor];
self.bottomInnerView.backgroundColor? ? = [UIColor grayColor];
[self.topView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.and.top.equalTo(self.view);? ? // 左邊、右邊、頂部 等于 self.View
}];
[self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.and.bottom.equalTo(self.view);? // 左邊、右邊、底部 等于 self.View
make.top.equalTo(self.topView.mas_bottom);? ? ? // 頂部 等于 topView 的 底部
make.height.equalTo(self.topView);? ? ? ? ? ? ? // 高 等于 topView
// 結(jié)果:上下55分成
}];
[self.topInnerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(self.topInnerView.mas_height).multipliedBy(3);? // 寬度是高度的3倍
make.width.and.height.lessThanOrEqualTo(self.topView);? ? ? ? ? ? ? // 寬度、高度 小于 topView的寬度高度
make.width.and.height.equalTo(self.topView).with.priorityLow();? ? // 寬度、高度 等于 topView的寬度高度 優(yōu)先級(jí) 低
make.center.equalTo(self.topView);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 中心點(diǎn)位置 等于 topView
}];
[self.bottomInnerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(self.bottomInnerView.mas_width).multipliedBy(3);// 高度是寬度的3倍
make.width.and.height.lessThanOrEqualTo(self.bottomView);? ? ? ? ? // 寬度、高度 小于 bottomView的寬度高度
make.width.and.height.equalTo(self.bottomView).with.priorityLow();? // 寬度、高度 等于 bottonView的寬度高度 優(yōu)先級(jí) 低
make.center.equalTo(self.bottomView);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 中心點(diǎn)位置 等于 bottonView
}];
}
@end
示例07
@interface _07_Basic_AnimatedViewController ()
@property (nonatomic,strong) UIView *greenView;
@property (nonatomic,strong) UIView *redView;
@property (nonatomic,strong) UIView *blueView;
@property (nonatomic,assign) NSInteger padding;
@property (nonatomic, assign) BOOL animating;
@property (nonatomic, strong) NSMutableArray *animatableConstraints;
@end
@implementation _07_Basic_AnimatedViewController
-(void)loadView
{
[super loadView];
self.greenView = [[UIView alloc]init];
self.redView? = [[UIView alloc]init];
self.blueView? = [[UIView alloc]init];
[self.view addSubview:self.greenView];
[self.view addSubview:self.redView];
[self.view addSubview:self.blueView];
}
- (void)viewDidLoad {
[super viewDidLoad];
_greenView.backgroundColor = UIColor.greenColor;
_redView.backgroundColor? = UIColor.redColor;
_blueView.backgroundColor? = UIColor.blueColor;
NSInteger padding = self.padding = 10;
_animatableConstraints = [NSMutableArray array];
UIEdgeInsets paddingInsets = UIEdgeInsetsMake(_padding,_padding,_padding,_padding); // 一開(kāi)始 green,red,blue的尺寸 再通過(guò)約束來(lái)改變
[_greenView mas_makeConstraints:^(MASConstraintMaker *make) {
// 添加約束的同時(shí)添加到數(shù)組
[_animatableConstraints addObjectsFromArray:@[
make.edges.equalTo(self.view).insets(paddingInsets).priorityLow(), // 優(yōu)先級(jí)低
make.bottom.equalTo(_blueView.mas_top).offset(-padding),? ? // green bottom 相對(duì) blue top -10
]];
make.size.equalTo(_redView); // 大小 = redView
make.height.equalTo(_blueView); // 高 = blue
}];
[_redView mas_makeConstraints:^(MASConstraintMaker *make) {
// 添加約束的同時(shí)添加到數(shù)組
[_animatableConstraints addObjectsFromArray:@[
make.edges.equalTo(self.view).insets(paddingInsets).priorityLow(), // 優(yōu)先級(jí)低
make.left.equalTo(_greenView.mas_right).offset(padding), // left 紅色 green right? 10
make.bottom.equalTo(_blueView.mas_top).offset(-padding), // bottom? 藍(lán)色 top -10
]];
make.size.equalTo(_greenView); // 大小 = green
make.height.equalTo(_blueView.mas_height); // 高 = blue
}];
[_blueView mas_makeConstraints:^(MASConstraintMaker *make) {
// 添加約束的同時(shí)添加到數(shù)組
[self.animatableConstraints addObjectsFromArray:@[
make.edges.equalTo(self.view).insets(paddingInsets).priorityLow(), // 優(yōu)先級(jí)低
]];
make.height.equalTo(_greenView);
}];
[self.view layoutIfNeeded];
// 可以注釋此部分,查看沒(méi)有動(dòng)畫(huà)時(shí)的效果
if (self.view) {
_animating = YES;
[self animateWithInvertedInsets:NO];
}
}
- (void)animateWithInvertedInsets:(BOOL)invertedInsets {
if (!_animating) return; // 是否需要?jiǎng)赢?huà)
NSInteger padding = invertedInsets ? 100 : _padding; // Yes 就縮小100 否 10
UIEdgeInsets paddingInsets = UIEdgeInsetsMake(padding, padding, padding, padding);
for (MASConstraint *constraint in _animatableConstraints) {
constraint.insets = paddingInsets;
}
[UIView animateWithDuration:1 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
[self animateWithInvertedInsets:!invertedInsets]; // 取相反值無(wú)限循環(huán)執(zhí)行動(dòng)畫(huà)
}];
}
@end
示例08
@interface _08_Bacony_LabelsViewController ()
@property (nonatomic,strong) UILabel *longLabel;
@property (nonatomic,strong) UILabel *shortLabel;
@property (nonatomic,strong) UILabel *contentLable;
@end
@implementation _08_Bacony_LabelsViewController
- (void)loadView
{
[super loadView];
_longLabel? = [[UILabel alloc]init];
_shortLabel = [[UILabel alloc]init];
_contentLable = [[UILabel alloc]init];
[self.view addSubview:_longLabel];
[self.view addSubview:_shortLabel];
[self.view addSubview:_contentLable];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"08_Bacony Labels";
_longLabel.numberOfLines = 0;
_longLabel.font =[UIFont systemFontOfSize:13];
_longLabel.backgroundColor = [UIColor redColor];
_longLabel.textColor = [UIColor darkGrayColor];
_longLabel.lineBreakMode = NSLineBreakByTruncatingTail;
_longLabel.text = @"Bacon ipsum dolor sit amet spare ribs fatback kielbasa salami, tri-tip jowl pastrami flank short loin rump sirloin. Tenderloin frankfurter chicken biltong rump chuck filet mignon pork t-bone flank ham hock.";
_shortLabel.numberOfLines = 1;
_shortLabel.textColor = [UIColor purpleColor];
_shortLabel.backgroundColor = [UIColor yellowColor];
_shortLabel.lineBreakMode = NSLineBreakByTruncatingTail;
_shortLabel.text = @"Bacon";
_contentLable.numberOfLines = 0;
_contentLable.font =[UIFont systemFontOfSize:13];
_contentLable.backgroundColor = [UIColor greenColor];
_contentLable.textColor = [UIColor darkGrayColor];
_contentLable.lineBreakMode = NSLineBreakByTruncatingTail;
_contentLable.text = @"楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客楓子的博客";
// 只設(shè)置left top
[_longLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(10);
make.top.equalTo(self.view).offset(10);
}];
// 只設(shè)置 centerY right
[_shortLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(_longLabel); //
make.right.equalTo(self.view).offset(-10);
}];
// top left right 根據(jù)文字多少自動(dòng)計(jì)算高度
[_contentLable mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_longLabel.mas_bottom).offset(10);
make.left.equalTo(@10);
make.right.equalTo(self.view).offset(-10);
}];
}
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
CGFloat width = CGRectGetMinX(self.shortLabel.frame)-10;
width -= CGRectGetMinX(self.longLabel.frame);
self.longLabel.preferredMaxLayoutWidth = width;
}
@end
示例09
@interface _09_UIScrollViewViewController ()
@property (nonatomic,strong) UIScrollView *scrollView;
@property (nonatomic,strong) UIView? ? ? *contentView;
@end
@implementation _09_UIScrollViewViewController
-(void)loadView
{
[super loadView];
_scrollView = [[UIScrollView alloc]init];
_contentView = [[UIView alloc]init];
[self.view addSubview:_scrollView];
[self.scrollView addSubview:_contentView];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"09_UIScrollView";
_scrollView.backgroundColor = [UIColor grayColor];
[_scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view); // self.view一樣大小
}];
_contentView.backgroundColor = [UIColor greenColor];
[_contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(_scrollView); // 大小? = _scrollView
make.width.equalTo(_scrollView); // width? = _scrollView
}];
UIView *lastView;
CGFloat height = 25;
for (int i = 0; i < 10; i++) {
UIView *view = [[UIView alloc]init];
view.backgroundColor = [self randomColor];
[_contentView addSubview:view];
// 點(diǎn)擊 改變透明度
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
[view addGestureRecognizer:singleTap];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(lastView ? lastView.mas_bottom : @0); // 第一個(gè)View top = 0;
make.left.equalTo(@0); // left 0
make.width.equalTo(_contentView); // width = _contentView;
make.height.equalTo(@(height)); // heinght = height
}];
height += 25; // += 25;
lastView = view;
}
[_contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(lastView); // bottom =? lastView
}];
}
- (UIColor *)randomColor {
CGFloat hue = ( arc4random() % 256 / 256.0 );? //? 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5;? //? 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5;? //? 0.5 to 1.0, away from black
return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
}
- (void)singleTap:(UITapGestureRecognizer*)sender {
[sender.view setAlpha:sender.view.alpha / 1.20]; // To see something happen on screen when you tap :O
[self.scrollView scrollRectToVisible:sender.view.frame animated:YES];
};
示例10
static CGFloat const kArrayExampleIncrement = 10.0;
@interface _10_ArrayViewController ()
@property (nonatomic,strong) UIView? *line;
@property (nonatomic,strong) UIButton *raiseButton;
@property (nonatomic,strong) UIButton *centerButton;
@property (nonatomic,strong) UIButton *lowerButton;
@property (nonatomic, assign) CGFloat offset;
@property (nonatomic, strong) NSArray *buttonViews;
@end
@implementation _10_ArrayViewController
-(void)loadView
{
[super loadView];
_line? ? ? ? = [[UIView alloc]init];
_raiseButton? = [UIButton buttonWithType:UIButtonTypeSystem];
_centerButton = [UIButton buttonWithType:UIButtonTypeSystem];
_lowerButton? = [UIButton buttonWithType:UIButtonTypeSystem];
[self.view addSubview:_line];
[self.view addSubview:_raiseButton];
[self.view addSubview:_centerButton];
[self.view addSubview:_lowerButton];
}
- (void)viewDidLoad {
[super viewDidLoad];
_line.backgroundColor = [UIColor redColor];
[_raiseButton setTitle:@"Raise" forState:UIControlStateNormal];
[_centerButton setTitle:@"Center" forState:UIControlStateNormal];
[_lowerButton setTitle:@"Lower" forState:UIControlStateNormal];
[_raiseButton addTarget:self action:@selector(raiseAction) forControlEvents:UIControlEventTouchUpInside];
[_centerButton addTarget:self action:@selector(centerAction) forControlEvents:UIControlEventTouchUpInside];
[_lowerButton addTarget:self action:@selector(lowerAction) forControlEvents:UIControlEventTouchUpInside];
// 添加跟中線,方便查看按鈕的移動(dòng)
[_line mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(self.view);
make.height.equalTo(@1);
make.center.equalTo(self.view);
}];
[_raiseButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).with.offset(10.0);
}];
[_centerButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
}];
[_lowerButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view).with.offset(-10);
}];
self.buttonViews = @[_raiseButton, _lowerButton, _centerButton];
}
- (void)centerAction {
self.offset = 0.0;
}
- (void)raiseAction {
self.offset -= kArrayExampleIncrement;
}
- (void)lowerAction {
self.offset += kArrayExampleIncrement;
}
- (void)setOffset:(CGFloat)offset {
_offset = offset;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:0.2 animations:^{
[self.view layoutIfNeeded];
}];
}
- (void)updateViewConstraints {
// 同時(shí)更新多個(gè)按鈕的約束
[self.buttonViews mas_updateConstraints:^(MASConstraintMaker *make) {
make.baseline.equalTo(self.view.mas_centerY).with.offset(self.offset); // buttonViews的底線
}];
[super updateViewConstraints];
}
@end
示例11
@interface _11_Attribute_ChainingViewController ()
@property (nonatomic,strong) UIView *greenView;
@property (nonatomic,strong) UIView *redView;
@property (nonatomic,strong) UIView *blueView;
@end
@implementation _11_Attribute_ChainingViewController
-(void)loadView
{
[super loadView];
_greenView = [[UIView alloc]init];
_redView? = [[UIView alloc]init];
_blueView? = [[UIView alloc]init];
[self.view addSubview:_greenView];
[self.view addSubview:_redView];
[self.view addSubview:_blueView];
}
- (void)viewDidLoad {
[super viewDidLoad];
UIEdgeInsets padding = UIEdgeInsetsMake(15, 10, 15, 10);
_greenView.backgroundColor = UIColor.greenColor;
[_greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.left.equalTo(self.view).insets(padding);? // 頂部15 左邊 10
make.bottom.equalTo(_blueView.mas_top).insets(padding); // 底部與藍(lán)色 15
make.width.equalTo(_redView.mas_width);? ? ? ? ? ? ? ? // 寬度與紅色相等
make.height.equalTo(@[_redView, _blueView]);? ? ? ? ? ? // 高度與紅藍(lán)相等
}];
_redView.backgroundColor = UIColor.redColor;
[_redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.and.right.equalTo(self.view).insets(padding);? // 頂部15 右邊 10
make.left.equalTo(_greenView.mas_right).insets(padding);// 左邊與綠色? 10
make.bottom.equalTo(_blueView.mas_top).insets(padding); // 底部與藍(lán)色? 15
make.width.equalTo(_greenView.mas_width);? ? ? ? ? ? ? // 寬度與紅色相等
make.height.equalTo(@[_greenView, _blueView]);? ? ? ? ? // 高度與綠藍(lán)相等
}];
_blueView.backgroundColor = UIColor.blueColor;
[_blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_greenView.mas_bottom).insets(padding);? // 頂部綠色 15
make.left.right.and.bottom.equalTo(self.view).insets(padding); // 左邊 10 右邊 10 底部 15
make.height.equalTo(@[_greenView, _redView]);? // 高度與紅綠相等
}];
}
@end
示例12
@interface _12_Layout_GuidesViewController ()
@property (nonatomic,strong) UIView *topView;
@property (nonatomic,strong) UIView *bottomView;
@end
@implementation _12_Layout_GuidesViewController
-(void)loadView
{
[super loadView];
_topView? ? = [[UIView alloc]init];
_bottomView = [[UIView alloc]init];
[self.view addSubview:_topView];
[self.view addSubview:_bottomView];
}
- (void)viewDidLoad {
[super viewDidLoad];
_topView.backgroundColor = UIColor.greenColor;
[_topView mas_makeConstraints:^(MASConstraintMaker *make) {
UIView *topLayoutGuide = (id)self.topLayoutGuide; //顯示屏幕內(nèi)容的垂直程度最高,使用自動(dòng)布局的約束。(只讀)
make.top.equalTo(topLayoutGuide.mas_bottom);
make.left.equalTo(self.view);
make.right.equalTo(self.view);
make.height.equalTo(@40);
}];
_bottomView.backgroundColor = UIColor.redColor;
[_bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
UIView *bottomLayoutGuide = (id)self.bottomLayoutGuide;
make.bottom.equalTo(bottomLayoutGuide.mas_top);
make.left.equalTo(self.view);
make.right.equalTo(self.view);
make.height.equalTo(@40);
}];
}
@end