一、viewController的属性edgesForExtendedLayout
如果我们使用masonry,这个属性的设置会非常方便的帮助我们解决计算偏移量的问题。
1.edgesForExtendedLayout是一个类型为UIExtendedEdge的属性,指定边缘要延伸的方向。默认是UIRectEdgeAll,四周边缘均延伸,从iOS7开始
如果即使视图中上有navigationBar,下有tabBar,那么视图仍会延伸覆盖到四周的区域。
2.假设在有navigation bar和tabbar的情况下:
该属性设置为UIRectEdgeBottom;那么就会self.view.frame是从navigationBar下面开始计算一直到屏幕底部;
该属性设置为UIRectEdgeTop;那么就会self.view.frame是从navigationBar上面计算面开始计算一直到屏幕tabBar上部;
该属性设置为UIRectEdgeNone;那么就会self.view.frame是从navigationBar下面开始计算一直到屏幕tabBar上部;
3.iOS7以上系统,self.navigationController.navigationBar.translucent默认为YES,self.view.frame.origin.y从0开始(屏幕最上部)。此时若是添加代码self.edgesForExtendedLayout = UIRectEdgeNone(iOS7.0以后方法);self.view.frame.origin.y会下移64像素至navBar下方开始。
#define kIOSVersion ((float)[[[UIDevice currentDevice] systemVersion] doubleValue])
在viewController中使用
if (kIOSVersion >= 7.0) {
self.automaticallyAdjustsScrollViewInsets = NO;
self.edgesForExtendedLayout = UIRectEdgeNone;
}
二、multipliedBy()、dividedBy()比例
使用multipliedBy必须是对同一个控件本身,比如,上面的代码中,我们都是对bottomInnerView.mas_width本身的,如果修改成相对于其它控件,会出问题。
dividedBy(3);可以不是
三、AutoLayout关于更新的几个方法的区别
setNeedsLayout:告知页面需要更新,但是不会立刻开始更新。执行后会立刻调用layoutSubviews。
layoutIfNeeded:告知页面布局立刻更新。所以一般都会和setNeedsLayout一起使用。如果希望立刻生成新的frame需要调用此方法,利用这点一般布局动画可以在更新布局后直接使用这个方法让动画生效。
layoutSubviews:系统重写布局
setNeedsUpdateConstraints:告知需要更新约束,但是不会立刻开始
updateConstraintsIfNeeded:告知立刻更新约束
updateConstraints:系统更新约束
四、Masonry使用注意事项
用mas_makeConstraints的那个view需要在addSubview之后才能用这个方法
mas_equalTo适用数值元素,equalTo适合多属性的比如make.left.and.right.equalTo(self.view)
方法and和with只是为了可读性,返回自身,比如make.left.and.right.equalTo(self.view)和make.left.right.equalTo(self.view)是一样的。
因为iOS中原点在左上角所以注意使用offset时注意right和bottom用负数。
五、重写updateViewConstraints方法
- (void)updateViewConstraints
ViewController的View在更新视图布局时,会先调用ViewController的updateViewConstraints 方法。我们可以通过重写这个方法去更新当前View的内部布局,而不用再继承这个View去重写-updateConstraints方法。我们在重写这个方法时,务必要调用 super 或者 调用当前View的 -updateConstraints 方法。
#import "ZYXSixViewController.h"
@interface ZYXSixViewController ()
@property (nonatomic, strong) UIButton * yellowButton;
@property (nonatomic, assign) BOOL buttonClicked;
@end
@implementation ZYXSixViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self p_setupViews];
}
- (void)p_setupViews
{
self.buttonClicked = NO;
//实例1
UIButton * yellowButton = [UIButton buttonWithType:UIButtonTypeCustom];
yellowButton.backgroundColor = [UIColor yellowColor];
[yellowButton setTitle:@"点击尺寸改变" forState:UIControlStateNormal];
[yellowButton setTitleColor:[UIColor blackColor] forState:
UIControlStateNormal];
yellowButton.layer.cornerRadius = 5;
[self.view addSubview:yellowButton];
self.yellowButton = yellowButton;
[yellowButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(100, 100));
make.center.equalTo(self.view);
}];
[yellowButton addTarget:self action:@selector(yellowButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)yellowButtonClicked:(UIButton *)sender{
self.buttonClicked = !self.buttonClicked;
// 告诉self.view约束需要更新
[self.view setNeedsUpdateConstraints];
// 调用此方法告诉self.view检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用
[self.view updateConstraintsIfNeeded];
[UIView animateWithDuration:1 animations:^{
// 告知页面布局立刻更新
[self.view layoutIfNeeded];
}];
}
- (void)updateViewConstraints
{
// 这里使用update也是一样的。
// remake会将之前的全部移除,然后重新添加
__weak __typeof(self) weakSelf = self;
[self.yellowButton mas_remakeConstraints:^(MASConstraintMaker *make) {
if (weakSelf.buttonClicked) {
make.top.bottom.mas_equalTo(0);
make.left.right.mas_equalTo(0);
}else{
make.size.mas_equalTo(CGSizeMake(100, 100));
make.center.equalTo(self.view);
}
}];
[super updateViewConstraints];
}