iOS-Masonry布局UIScrollView

原创
2016/03/15 00:38
阅读数 1.3K

前言

IOS自动布局有sb、xib自适应或者是纯代码编写frame布局,前者本人不太喜欢,后者计算太多也是比较繁琐,masonry这个第三方库,其实是封装了autolayout的约束,易于我们使用纯代码编写自适应布局。

 

(一)下面的这个例子是一个绑定手机号成功的页面布局;

#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至少等于屏幕高度。

 

总结

uiscrollview是一个比较特殊的视图,使用自适应布局的话contentsize的大小取决于subviews,所以在布局时要特别的注意,不然会出现约束冲突。网络上看到一个布局原则:整体frame布局,局部masonry自适应布局。

展开阅读全文
打赏
1
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
1
分享
返回顶部
顶部