SDAutoLayout
1、下載 SDAutoLayout 很簡單渊啰,而且只有兩個分類
image.png
2探橱、注釋的也很清楚
image.png
3、下面是我自己做自動布局和自適應(yīng)Cell高度測試的例子
自動布局的代碼使用非常簡單
_headImageView.sd_layout
.leftEqualToView(self.contentView)
.topSpaceToView(self.contentView, 10)
.rightEqualToView(self.contentView)
.heightIs(200)
.widthIs([UIScreen mainScreen].bounds.size.width);
自適應(yīng)Cell高度的代碼也很簡單
第一步,在給Cell賦值的時候绘证,賦值結(jié)束需要把Cell的最下面的一個組件明確給出來
- (void)setSdModel:(SDModel *)sdModel {
_titleLabel.text=sdModel.title;
_timeLabel.text=sdModel.time;
// _titleLabel 自適應(yīng)高度隧膏,不需要手動的計算文本的高度
_titleLabel.sd_layout.autoHeightRatio(0);
// lable的text為attributedString 時,需要進(jìn)行設(shè)置
// _titleLabel.isAttributedContent =YES;
// _timeLabel 是最后一個組件 嚷那,bottomMargin 是 距離底部的距離
[self setupAutoHeightWithBottomView:_timeLabel bottomMargin:10];
// 如果不知道哪個view是最后一個胞枕,可以傳遞 可能是最后一個view的 數(shù)組
// [self setupAutoHeightWithBottomViewsArray:<#(NSArray *)#> bottomMargin:<#(CGFloat)#>]
}
第二步, heightForRowAtIndexPath
方法里面不應(yīng)返回高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// ForIndexPath: 當(dāng)前的cell的位置
// model: 當(dāng)前cell的數(shù)據(jù)模型(需要使用KVC進(jìn)行賦值)
// keyPath: 就是cell的數(shù)據(jù)模型對象,此文中就是cell.sdModel
// cellClass: 就是cell的類名
// contentViewWidth: cell的寬度
return [tableView cellHeightForIndexPath:indexPath model:[self.dataSource objectAtIndex:indexPath.row] keyPath:@"sdModel" cellClass:[mySDCell class] contentViewWidth:self.view.frame.size.width];
}
ViewController
//
// ViewController.m
// iOSXC
//
// Created by 尼古拉斯·澄嚎恚·穆罕默德 on 2017/11/22.
// Copyright ? 2017年 CHJ. All rights reserved.
//
#import "ViewController.h"
#import "SDAutoLayout.h"
#import "mySDCell.h"
#import "SDModel.h"
@interface ViewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic,strong) NSMutableArray *dataSource;
@property (nonatomic,strong) UITableView *tableView;
@end
@implementation ViewController
#pragma mark - 生命周期
- (void)viewDidLoad {
[super viewDidLoad];
[self initSubView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - 初始化子控件
- (void)initSubView {
// 先添加子組件腐泻,再進(jìn)行子組件的布局
[self.view addSubview:self.tableView];
self.tableView.sd_layout.leftEqualToView(self.view).rightEqualToView(self.view).topEqualToView(self.view).bottomEqualToView(self.view);
}
#pragma mark - set and get
- (UITableView *)tableView {
if (!_tableView){
_tableView=[[UITableView alloc]init];
_tableView.delegate=self;
_tableView.dataSource=self;
}
return _tableView;
}
- (NSMutableArray *)dataSource {
if (!_dataSource) {
_dataSource = [NSMutableArray new];
NSArray *data = @[@{@"imageURL": @"",
@"title":@"上面寫到要將控件的布局寫在同一個方法中决乎,方便之后查看與修改,但關(guān)于布局的選型也是需要精心考慮的贫悄,如果直接使用CGRectMake可讀性會很差瑞驱,因為只通過x,y,width,height是不能確定View與View之間的位置關(guān)系的。 github上關(guān)于iOS布局的第三方也是有很多的窄坦,看公司架構(gòu)而定,個人比較喜歡SDAutoLayout凳寺,這個布局庫語法簡單鸭津,功能完善,而且代碼可讀性很好肠缨。",
@"time":@"2017.11.30"
},
@{@"imageURL": @"",
@"title":@"storyboard和xib是蘋果提供給開發(fā)者的一種可視化編程方式逆趋,對于它的好與壞,想必各位都有自己的看法晒奕,但我在項目中是極力避免使用xib來布局的闻书,因為我總認(rèn)為它的缺點(diǎn)多過優(yōu)點(diǎn)",
@"time":@"2017.11.30"
},
@{@"imageURL": @"",
@"title":@"對于復(fù)雜的、動態(tài)生成的界面脑慧,建議使用手工編寫界面魄眉。",
@"time":@"2017.11.30"
},
@{@"imageURL": @"",
@"title":@"對于需要統(tǒng)一風(fēng)格的按鈕或UI控件,建議使用手工用代碼來構(gòu)造闷袒。方便之后的修改和復(fù)用坑律。",
@"time":@"2017.11.30"
},
@{@"imageURL": @"",
@"title":@"在iOS開發(fā)領(lǐng)域內(nèi),UIViewController承載了非常多的事情囊骤,比如View的初始化晃择,業(yè)務(wù)邏輯,事件響應(yīng)也物,數(shù)據(jù)加工等等宫屠,當(dāng)然還有更多我現(xiàn)在也列舉不出來,但是我們知道有一件事情Controller肯定逃不掉要做:協(xié)調(diào)V和M滑蚯。也就是說浪蹂,不管怎么拆,協(xié)調(diào)工作是拆不掉的根據(jù)第一心法拆開來的東西膘魄,很有可能還是強(qiáng)業(yè)務(wù)相關(guān)的乌逐,這種情況有的時候無法避免。但我們拆也要拆得好看创葡,拆出來的部分最好能夠歸成某一類對象浙踢,然后最好能夠抽象出一個通用邏輯出來,使他能夠復(fù)用灿渴。即使不能抽出通用邏輯洛波,那也盡量抽象出一個protocol胰舆。拆分的粒度要盡可能大一點(diǎn),封裝得要透明一些蹬挤。唐巧說一切隱藏都是對代碼復(fù)雜性的增加缚窿,除非它帶來了好處,這在一定程度上有點(diǎn)道理焰扳,沒有好處的隱藏確實(shí)都不好(笑)倦零。提高抽象度事實(shí)上就是增加封裝的力度,將一個負(fù)責(zé)的業(yè)務(wù)抽象成只需要很少的輸入就能完成吨悍,就是高度抽象扫茅。嗯,繼承很多層育瓜,這種做法雖然也提高了抽象程度葫隙,但我不建議這么玩。我不確定唐巧在這里說的隱藏跟我說的封裝是不是同一個概念躏仇,但我在這里想提倡的是盡可能提高抽象程度",
@"time":@"2017.11.30"
}];
for (int i=0; i<[data count]; i++) {
NSDictionary *diction=[data objectAtIndex:i];
SDModel *model=[SDModel new];
[model setValuesForKeysWithDictionary:diction];
[_dataSource addObject:model];
}
}
return _dataSource;
}
#pragma mark -UITableView Delegete and dataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.dataSource count];
}
- (mySDCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
mySDCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell=[[mySDCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
cell.sdModel = [self.dataSource objectAtIndex:indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [tableView cellHeightForIndexPath:indexPath model:[self.dataSource objectAtIndex:indexPath.row] keyPath:@"sdModel" cellClass:[mySDCell class] contentViewWidth:self.view.frame.size.width];
}
@end
Model
//
// SDModel.h
// iOSXC
//
// Created by 尼古拉斯·沉到牛·穆罕默德 on 2017/11/30.
// Copyright ? 2017年 CHJ. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface SDModel : NSObject
@property (nonatomic,copy)NSString *imageURL;
@property (nonatomic,copy)NSString *title;
@property (nonatomic,copy)NSString *time;
@end
Cell.h
//
// mySDCell.h
// iOSXC
//
// Created by 尼古拉斯·常·穆罕默德 on 2017/11/30.
// Copyright ? 2017年 CHJ. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "SDModel.h"
@interface mySDCell : UITableViewCell
// 聲明數(shù)據(jù)對象
@property (nonatomic, strong)SDModel *sdModel;
@end
Cell.m
//
// mySDCell.m
// iOSXC
//
// Created by 尼古拉斯·逞媸郑·穆罕默德 on 2017/11/30.
// Copyright ? 2017年 CHJ. All rights reserved.
//
#import "mySDCell.h"
#import "SDAutoLayout.h"
@interface mySDCell ()
@property (nonatomic, strong)UIImageView *headImageView;
@property (nonatomic, strong)UILabel *titleLabel;
@property (nonatomic, strong)UILabel *timeLabel;
@end
@implementation mySDCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self initSubViews];
}
return self;
}
- (void)initSubViews {
_headImageView = [UIImageView new];
_headImageView.backgroundColor=[UIColor redColor];
_titleLabel = [[UILabel alloc]init];
_titleLabel.textColor = [UIColor blackColor];
_timeLabel = [[UILabel alloc]init];
_timeLabel.textAlignment = NSTextAlignmentRight;
_timeLabel.font = [UIFont systemFontOfSize:12.0];
// 統(tǒng)一添加子組件,先添加子組件糟描,在進(jìn)行子組件的布局
[self.contentView sd_addSubviews:@[_headImageView, _titleLabel, _timeLabel]];
// 子組件布局
_headImageView.sd_layout
.leftEqualToView(self.contentView)
.topSpaceToView(self.contentView,10)
.rightEqualToView(self.contentView)
.heightIs(200)
.widthIs([UIScreen mainScreen].bounds.size.width);
_titleLabel.sd_layout
.leftSpaceToView(self.contentView, 10)
.topSpaceToView(self.headImageView, 10)
.rightSpaceToView(self.contentView, 10)
.heightIs(30)
.widthIs([UIScreen mainScreen].bounds.size.width-20);
_timeLabel.sd_layout
.topSpaceToView(self.titleLabel, 10)
.rightSpaceToView(self.contentView, 10)
.heightIs(20);
}
- (void)setSdModel:(SDModel *)sdModel {
_titleLabel.text=sdModel.title;
_timeLabel.text=sdModel.time;
// _titleLabel 自適應(yīng)高度,不需要手動的計算文本的高度
_titleLabel.sd_layout.autoHeightRatio(0);
// lable的text為attributedString 時册倒,需要進(jìn)行設(shè)置
// _titleLabel.isAttributedContent =YES;
[self setupAutoHeightWithBottomView:_timeLabel bottomMargin:10];
// 設(shè)置label最大顯示的行數(shù)
// [_titleLabel setMaxNumberOfLinesToShow:10];
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end