OC - Masonry的基本使用(tableView作为实例)

随着约束布局的越来越流行,很多项目正在逐步由frame布局转移到约束布局。最近就有几个朋友说道,新项目要求用约束来布局,而用约束来进行布局,Masonry作为一个强大的三方库,就不得不提了。此篇文章,就是简单的使用Masonry来进行布局,以tableView为实例,进行讲解,在demo里会有相应的注释。这个demo,感觉能满足基本的需求,若有哪里不足或不正确,欢迎指出。

注意:如果你的项目,父视图是ScrollView,那么我建议你,还是不要用Masonry。scrollView自身就是有约束设置的,再用Masonry进行子视图的约束,子视图的约束将会失效,当然如果你有很长的时间来研究scrollView自身约束和Masonry库约束的冲突的话(这里姑且让我用冲突这个词语吧),那你可以肆无忌惮的使用Masonry库了。


效果图在结尾处

下面直接贴代码:

ViewController.m文件

#import "ViewController.h"
#import "TableViewCell.h"
#import "TableViewModel.h"
#import "TableHeaderView.h"

#import "Masonry.h"

@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>

@property (nonatomic,strong)TableHeaderView    *headerView;
@property (nonatomic,strong)UITableView        *tableView;
@property (nonatomic,strong)NSMutableArray     *dataSource;

@end

static NSString *const cellIdentifier =@"cellIdentifier";

@implementation ViewController

- (void)viewDidLoad
{
    [superviewDidLoad];
    
    [self loadData];
}

- (void)loadData
{
    self.dataSource = [NSMutableArrayarrayWithCapacity:0];
    
    for (int i =0; i <20; i++)
    {
        TableViewModel *model = [[TableViewModelalloc]init];
        if (i %2 ==0)
        {
            model.isLeft = @"1";
            model.title = @"这是左侧的title";
            model.headerTitle =@"这是imageView在左侧的组头上的title";
        }
        else
        {
            model.isLeft = @"0";
            model.title =@"这是右侧的title这是右侧的title";
            model.headerTitle =@"这是imageView在右侧的组头上的title";
        }
        [self.dataSourceaddObject:model];
    }
    
    [self.tableViewreloadData];
}

- (UITableView *)tableView
{
    if (_tableView ==nil)
    {
        //使用约束布局,将frame置为CGRectZero
        self.tableView = [[UITableViewalloc]initWithFrame:CGRectZerostyle:UITableViewStyleGrouped];
        self.tableView.delegate =self;
        self.tableView.dataSource =self;
        self.tableView.rowHeight =86.0f;
        [self.tableViewregisterClass:[TableViewCellclass]forCellReuseIdentifier:cellIdentifier];
        [self.viewaddSubview:self.tableView];
        
        //此处约束设置,必须保证此对象已经添加到父视图上
        [self.tableViewmas_makeConstraints:^(MASConstraintMaker *make) {
           
            //头部相对于父视图10个像素
            make.top.equalTo(self.view.mas_top).offset(20);
           //相对父视图做约束(此处表示:左,右部,均相对于父视图0个像素。此处代码不唯一,cell中另有其他写法)
            make.left.and.right.equalTo(self.view);
           //底部相对于父视图10个像素(注意:设置底部和右侧约束时,要使用负数)
            make.bottom.equalTo(self.view).offset(-10);
            
            //mas_equalTo方法,设置绝对距离
//            make.height.mas_equalTo([UIScreen mainScreen].bounds.size.height - 10);
        }];
    }
    return_tableView;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return self.dataSource.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    TableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:cellIdentifierforIndexPath:indexPath];
    
    if (self.dataSource.count >0)
    {
        TableViewModel *model = self.dataSource[indexPath.section];
        [cell configCellWithModel:model];
    }
    return cell;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    /**
     
        此处为tableView的组头view,注意,此处组头view要使用frame来进行布局,不能使用Masonry约束布局。
     
        原因:组头view本身所属于tableView,并没有兄弟/父子视图关系,使用Masonry进行约束布局,只能作用于父子/兄弟视图间。
     
        我是这么理解的,可能理解有误,在这里我只是提醒一下,不能使用Masonry对组头视图布局,组尾视图是一样的道理。
     
     */
    TableHeaderView *headerView = [[TableHeaderViewalloc]initWithFrame:CGRectMake(0,0,self.view.frame.size.width,50)];
    
    TableViewModel *model = self.dataSource[section];
    
    [headerView configHeaderViewWithModel:model];
    
    return headerView;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0.01;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 50.0f;
}
- (void)didReceiveMemoryWarning
{
    [superdidReceiveMemoryWarning];
}

@end

Cell类

TableViewCell.h 文件

#import <UIKit/UIKit.h>

@class TableViewModel;
@interface TableViewCell : UITableViewCell

@property (nonatomic,strong)UIImageView    *imgView;
@property (nonatomic,strong)UILabel        *titleLabel;

- (void)configCellWithModel:(TableViewModel *)model;

@end

TableViewCell.m 文件

#import "TableViewCell.h"
#import "TableViewModel.h"
#import "Masonry.h"

static CGFloat width =220;

@implementation TableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [superinitWithStyle:stylereuseIdentifier:reuseIdentifier];
    if (self)
    {
        self.selectionStyle =UITableViewCellSelectionStyleNone;
        [self configUI];
    }
    return self;
}

- (void)configUI
{
    if (!self.imgView)
    {
        self.imgView = [UIImageViewnew];
        [self.contentViewaddSubview:self.imgView];
        
        //初始化设置约束
        [self.imgViewmas_makeConstraints:^(MASConstraintMaker *make) {
            
            //设置左侧相对于父视图20个像素
            make.left.equalTo(self.contentView.mas_left).offset(20);
            //设置y坐标中心点
            make.centerY.equalTo(self.contentView.mas_centerY);
            //设置宽和高的绝对距离
            make.width.mas_equalTo(100);
            make.height.mas_equalTo(66);
        }];
    }
    
    if (!self.titleLabel)
    {
        self.titleLabel = [UILabelnew];
        self.titleLabel.font = [UIFontsystemFontOfSize:15];
        self.titleLabel.backgroundColor = [UIColorlightGrayColor];
        self.titleLabel.textColor = [UIColorwhiteColor];
        [self.contentViewaddSubview:self.titleLabel];
        
        [self.titleLabelmas_makeConstraints:^(MASConstraintMaker *make) {
            
           //此对象的左侧,相对于兄弟视图的右侧做约束
            make.left.equalTo(self.imgView.mas_right).offset(10);
            make.centerY.equalTo(self.contentView.mas_centerY);
            make.height.mas_equalTo(30);
            
           //若不给对象设置宽度,则此对象的宽度以展示的文字长度为宽度,但此时其他兄弟视图不能以此对象的右侧作为约束对象,
            
           //若类似于此demo这种场景,兄弟视图在模型赋值时改变位置,而此时此对象并未主动更新约束位置。当兄弟视图改变位置后,此对象也会根据兄弟视图进行位置变换,不过此对象相对于兄弟视图的位置不会改变
        }];
    }
}

- (void)configCellWithModel:(TableViewModel *)model
{
    if ([model.isLeftintegerValue] ==1)
    {
        self.titleLabel.text = model.title;
        
        [self.imgViewsetImage:[UIImageimageNamed:@"1.jpg"]];
        
        //当已经初始化了约束,而此时此对象的位置需要改变,则使用mas_updateConstraints方法,更新约束位置
        [self.imgViewmas_updateConstraints:^(MASConstraintMaker *make) {
            
           //设置对象相对于父视图约束还可以这样写
            make.left.equalTo(@20);
            make.right.equalTo(self.contentView).offset(- ([UIScreenmainScreen].bounds.size.width -120));
        }];
    }
    else
    {
        self.titleLabel.text = model.title;

        [self.imgViewsetImage:[UIImageimageNamed:@"2.jpg"]];
        [self.imgViewmas_updateConstraints:^(MASConstraintMaker *make) {
            
           //设置对象相对于父视图约束也可以这样写
            make.left.offset([UIScreenmainScreen].bounds.size.width -100 - width);
            make.right.offset(-width);
        }];
    }
}

@end

模型类

TableViewModel.h文件

#import <Foundation/Foundation.h>

@interface TableViewModel : NSObject

@property (nonatomic,copy)NSString     *isLeft;
@property (nonatomic,copy)NSString     *title;
@property (nonatomic,copy)NSString     *headerTitle;

@end

组头类

TableHeaderView.h 文件

#import <UIKit/UIKit.h>

@class TableViewModel;
@interface TableHeaderView : UIView

@property (nonatomic,strong)UILabel    *headerTitleLabel;

- (void)configHeaderViewWithModel:(TableViewModel *)model;

@end

TableHeaderView.m 文件
#import"TableHeaderView.h"
#import "TableViewModel.h"

#import "Masonry.h"
@implementation TableHeaderView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [superinitWithFrame:frame];
    if (self)
    {
        self.backgroundColor = [UIColorgrayColor];

        [self configUI];
    }
    return self;
}

- (void)configUI
{
    if (!self.headerTitleLabel)
    {
        self.headerTitleLabel = [UILabelnew];
        self.headerTitleLabel.font = [UIFontsystemFontOfSize:15];
        self.headerTitleLabel.textAlignment = NSTextAlignmentCenter;
        self.headerTitleLabel.textColor = [UIColorwhiteColor];
        [selfaddSubview:self.headerTitleLabel];
        
        [self.headerTitleLabelmas_makeConstraints:^(MASConstraintMaker *make) {
            
            make.centerX.equalTo(self.mas_centerX);
            make.centerY.equalTo(self.mas_centerY);
            make.height.mas_equalTo(30);

            //此处不约束宽度也是可以的
            make.width.mas_equalTo([UIScreenmainScreen].bounds.size.width);
        }];
    }
}

- (void)configHeaderViewWithModel:(TableViewModel *)model
{
    self.headerTitleLabel.text = model.headerTitle;
}

@end





  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值