前言網絡
IOS自動佈局有sb、xib自適應或者是純代碼編寫frame佈局,前者本人不太喜歡,後者計算太多也是比較繁瑣,masonry這個第三方庫,實際上是封裝了autolayout的約束,易於咱們使用純代碼編寫自適應佈局。ide
(一)下面的這個例子是一個綁定手機號成功的頁面佈局;佈局
#import "BindSuccessViewController.h" #import <Masonry.h> #define SCREEN_WIDTH CGRectGetWidth([UIScreen mainScreen].bounds) @interface BindSuccessViewController () { UIImageView *imageView; UILabel *alertlabel; UIImageView *hfImageView; UIButton *sureButton; UIButton *cancelButton; UIScrollView *scrollView; UIView *layoutView; } @end @implementation BindSuccessViewController - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"修改手機號"; self.view.backgroundColor = [UIColor whiteColor]; self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back"] style:UIBarButtonItemStylePlain target:self action:@selector(clickCancelButton)]; [self initView]; [self configView]; } - (void)initView { scrollView = [UIScrollView new]; scrollView.bounces = NO; scrollView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:scrollView]; layoutView = [UIView new]; layoutView.backgroundColor = [UIColor whiteColor]; [scrollView addSubview:layoutView]; imageView = [UIImageView new]; imageView.image = [UIImage imageNamed:@"success"]; [layoutView addSubview:imageView]; alertlabel = [UILabel new]; alertlabel.preferredMaxLayoutWidth = SCREEN_WIDTH - 30; alertlabel.numberOfLines = 0; alertlabel.text = @"您已經成功的修改手機號!"; alertlabel.font = [UIFont systemFontOfSize:14.0f]; alertlabel.textAlignment = NSTextAlignmentCenter; [layoutView addSubview:alertlabel]; hfImageView = [UIImageView new]; hfImageView.image = [UIImage imageNamed:@"setting-hf"]; [layoutView addSubview:hfImageView]; sureButton = [UIButton buttonWithType:UIButtonTypeCustom]; sureButton.backgroundColor = [UIColor colorWithRed:0 green:160.0f/255 blue:223.0f/255 alpha:1.0f]; [sureButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [sureButton setTitle:@"肯定" forState:UIControlStateNormal]; [sureButton addTarget:self action:@selector(clickSureButton) forControlEvents:UIControlEventTouchUpInside]; [layoutView addSubview:sureButton]; cancelButton = [UIButton buttonWithType:UIButtonTypeCustom]; cancelButton.layer.borderWidth = 1.0f; cancelButton.layer.borderColor = [UIColor colorWithRed:0 green:160.0f/255 blue:223.0f/255 alpha:1.0f].CGColor; [cancelButton setTitle:@"取消" forState:UIControlStateNormal]; [cancelButton setTitleColor:[UIColor colorWithRed:0 green:160.0f/255 blue:223.0f/255 alpha:1.0f] forState:UIControlStateNormal]; [cancelButton addTarget:self action:@selector(clickCancelButton) forControlEvents:UIControlEventTouchUpInside]; [layoutView addSubview:cancelButton]; } - (void)configView { [scrollView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; [layoutView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.top.mas_equalTo(0); make.width.mas_equalTo(self.view); make.bottom.equalTo(cancelButton.mas_bottom).offset(20); }]; [imageView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(layoutView).offset(20); make.centerX.equalTo(scrollView); make.width.mas_equalTo(@60); make.height.mas_equalTo(@60); }]; [alertlabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(imageView.mas_bottom).offset(15); make.left.equalTo(layoutView).offset(15); make.right.equalTo(layoutView).offset(-15); }]; [hfImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(alertlabel.mas_bottom).offset(30); make.centerX.equalTo(scrollView); make.width.mas_equalTo(@277); make.height.mas_equalTo(@165); }]; [sureButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(hfImageView.mas_bottom).offset(20); make.left.equalTo(layoutView).offset(15); make.right.equalTo(layoutView).offset(-15); make.height.mas_equalTo(@40); }]; [cancelButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(sureButton.mas_bottom).offset(20); make.left.equalTo(sureButton); make.right.equalTo(sureButton); make.height.mas_equalTo(@40); }]; [scrollView mas_updateConstraints:^(MASConstraintMaker *make) { make.bottom.mas_equalTo(layoutView.mas_bottom).priorityLow(); make.bottom.mas_greaterThanOrEqualTo(self.view); }]; } - (void)clickSureButton { } - (void)clickCancelButton { [self.navigationController popToRootViewControllerAnimated:YES]; } @end
解釋一下一段,使得cancelButton始終會離底部有一段距離,[scrollView mas_updateConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(layoutView.mas_bottom).priorityLow();
make.bottom.mas_greaterThanOrEqualTo(self.view);
}]; 這段約束的意思是,先設置了scrollview的bottom等於layoutView的底部+20,可是它的優先級最低,而後又設置了scrollview的bottom大於或等於self.view,也就是說scrollview的contentSize.height至少等於屏幕高度。ui
總結code
uiscrollview是一個比較特殊的視圖,使用自適應佈局的話contentsize的大小取決於subviews,因此在佈局時要特別的注意,否則會出現約束衝突。網絡上看到一個佈局原則:總體frame佈局,局部masonry自適應佈局。orm