Autolayout进阶之代码编写约束(二)

上篇文章Autolayout进阶之代码编写约束(一)中介绍了怎么用Masonry来实现代码编写约束,这篇文章就来探讨下怎么使用SDAutolayout来编写约束。由于我平时使用的是Masonry,对SDAutolayout也是刚接触,所以写下这篇文章探讨学习。下面直接进入正题。

SDAutolayout框架


  • 支持Cell和Tableview高度自适应,Label和ScrollView内容自适应,致力于做最简单易用的AutoLayout库(摘自github)
  • github地址:https://github.com/gsdios/SDAutoLayout
  • 推荐用cocoapods安装

首先我们来进行基础的约束编程,导入头文件#import "UIView+SDAutoLayout.h"

//初始化一个view
UIView * redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
//然后将这个view添加到界面上
[self.view addSubview:redView];
//然后进行约束设置
redView
.sd_layout
.leftSpaceToView(self.view,100)
.rightSpaceToView(self.view,100)
.heightIs(100)
.topSpaceToView(self.view,100);

Autolayout进阶之代码编写约束(二)_第1张图片
运行结果

SDAutoLayout 使用的是链式编程,看上去比 Masonry简洁,而且也比较直观。

基本使用方法


Autolayout进阶之代码编写约束(二)_第2张图片
基本约束方法

sd_layout方法

开始自动布局的标志,后边直接跟约束方法。

xxxxSpaceToView(view,num)方法

用法看图片就已经很直观了,主要传递2个参数,参照控件和距离的值。用为采用链式编程,只要.方法名就能实现约束布局。

widthIs(num) && heightIs(num)

这两个方法分别设置view的宽度和高度的约束。

xxxEqualToView(view)方法

这个方法和xib拖约束一样,设置某控件的位置相对于另一个控件的位置。比如控件A与控件B的顶部相等:topEqualToView(B)

widthRatioToView(view,num)方法

设置两个控件的宽度相等,或者一个控件的宽度是另外一个的几倍,高度的使用方法和这个方法一样。

疑问

//初始化一个view
UIView * redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];

UIView * greenView =[[UIView alloc]init];
greenView.backgroundColor = [UIColor greenColor];

//然后将这个view添加到界面上
[self.view addSubview:redView];
[self.view addSubview:greenView];
//然后进行约束设置
redView
.sd_layout
.leftSpaceToView(self.view,50)
.heightIs(100)
.topSpaceToView(self.view,100);

greenView
.sd_layout
.widthRatioToView(redView,1)
.rightSpaceToView(self.view,50)
.topEqualToView(redView)
.heightIs(100)
.leftSpaceToView(redView,8);//实际运行这个约束居然没有实现
Autolayout进阶之代码编写约束(二)_第3张图片
实现结果

这是一个想实现自动计算等宽的约束布局,但是其中有条约束并没有执行(虽然编译器也没有出现约束错误提示)。我们可以发现,最后一条间距为8的约束并没有实现。其次我还发现一个问题(可能是我并不熟悉这个框架),我查看了文档,并没有发现怎么设置约束的优先级!如果少了优先级,这个框架的实际运用就大打折扣。

cell高度自动计算尝试


SDAutolayout的一大特点就是能自动计算cell高度,而且帮助开发者做了高度缓存,这个功能我当然也不能错过,下面是我体验的结果。

1. >> 设置cell高度自适应:
// cell布局设置好之后调用此方法就可以实现高度自适应(注意:如果用高度自适应则不要再以cell的底边为参照去布局其子view)
[cell setupAutoHeightWithBottomView:_view4 bottomMargin:10];

2. >> 获取自动计算出的cell高度

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id model = self.modelsArray[indexPath.row];
    // 获取cell高度
    return [self.tableView   cellHeightForIndexPath:indexPath model:model keyPath:@"model" cellClass:[DemoVC9Cell class]  contentViewWidth:cellContentViewWith];
}

首先第一点,[cell setupAutoHeightWithBottomView:_view4 bottomMargin:10];一开始我把这句代码写在了viewController上,结果各种报错,后来下载了demo才发现是写在cell中的,代码如下:

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
    [self setup];
}
    return self;
}

- (void)setup
{
    _titleLabel = [UILabel new];
    [self.contentView addSubview:_titleLabel];
    _titleLabel.textColor = [UIColor darkGrayColor];
    _titleLabel.font = [UIFont systemFontOfSize:15];
    _titleLabel.numberOfLines = 0;

    _imageView = [UIImageView new];
   [self.contentView addSubview:_imageView];
   _imageView.layer.borderColor = [UIColor grayColor].CGColor;
   _imageView.layer.borderWidth = 1;


    CGFloat margin = 15;
    UIView *contentView = self.contentView;

    _titleLabel.sd_layout
    .leftSpaceToView(contentView, margin)
    .topSpaceToView(contentView, margin)
    .rightSpaceToView(contentView, 120)
    .autoHeightRatio(0);

    _imageView.sd_layout
    .topEqualToView(_titleLabel)
    .leftSpaceToView(_titleLabel, margin)
    .rightSpaceToView(contentView, margin)
    .heightIs(60);

    // 当你不确定哪个view在自动布局之后会排布在cell最下方的时候可以调用次方法将所有可能在最下方的view都传过去
    [self setupAutoHeightWithBottomViewsArray:@[_titleLabel, _imageView] bottomMargin:margin];
}

其次,生成的cell必须含model属性如:@property (nonatomic, strong) DemoVC7Model *model;.m中要实现set方法,而且这个model名称不能变,否则也是崩溃。

- (void)setModel:(DemoVC7Model *)model
{
    _model = model;

    _titleLabel.text = model.title;
    _imageView.image = [UIImage imageNamed:model.imagePathsArray.firstObject];
}

只有这样才能实现自动计算高度,否则就各种崩溃。
最后实现的效果:

Autolayout进阶之代码编写约束(二)_第4张图片
自动cell高度尝试

如果仔细看,你会发现cell的高度并没有算对,label下面多了一行,如果去掉点label的内容,那多出的空白行又消失了。

总结

  • SDAutolayout来写约束的不错的,命名十分简洁,但是不能设置约束(如有错误,请指正),这个使整个框架的实用性大打折扣。
  • 虽然自动适应高度可以实现并且确实做了高度缓存,但是有很多约束,比如必须用set方法给cell赋值,必须告诉框架最后一个View是哪个。

我是翻滚的牛宝宝,欢迎大家评论交流~

你可能感兴趣的:(Autolayout进阶之代码编写约束(二))