![](https://img.haomeiwen.com/i1419035/ad4bcf5641ce5d56.jpg)
先看效果
Untitled.gif
需求是这样的
![](https://img.haomeiwen.com/i1419035/58f295e0705111ce.png)
![](https://img.haomeiwen.com/i1419035/4617362fead35c7c.png)
分析需求:可以观察到这个页面的顶部地址和底部优惠券商品金额立减运费合计金额提交订单是在固定位置上,所以顶部我打算用tableView的header做,再看订单,这部分相对复杂,可以推理出可能有多个订单,每个订单下又可能有多个商品,所以这部分我打算用分组做.在看里面的cell,有五种不不同的样式,但是布局都相对简单,我打算用tilte和textField去做,因为cell的右侧有的可能会有箭头或者文字,而textField有一个属性是leftView我可以把箭头包装在leftView这样可以保证cell右侧的整齐美观,同时又不用创建过多的控件导致维护艰难,分析完毕现在开始代码.
新创建一个GHDetailHeaderView继承UIView,头部有五个控件分别是两侧的两个图标和三个label,所以先声明这个几个控件
/** 位置 */
@property (nonatomic , strong) UIImageView *position;
/** 收货人 */
@property (nonatomic , strong) UILabel *receiver;
/** 向右箭头 */
@property (nonatomic , strong) UIImageView *arrow;
/** 电话号码 */
@property (nonatomic , strong) UILabel *phoneNum;
/** 地址 */
@property (nonatomic , strong) UILabel *address;
懒加载这些控件
- (UILabel *)address {
if (_address == nil) {
_address = [[UILabel alloc]init];
_address.text = @"地址: 开始计算价钱开始计算价钱开始计算价钱开始计算价钱";
_address.numberOfLines = 0;
_address.textColor = [UIColor lightGrayColor];
_address.font = [UIFont systemFontOfSize:14];
}
return _address;
}
- (UILabel *)phoneNum {
if (_phoneNum == nil) {
_phoneNum = [[UILabel alloc]init];
_phoneNum.text = @"13836172531";
_phoneNum.textColor = [UIColor lightGrayColor];
_phoneNum.font = [UIFont systemFontOfSize:14];
}
return _phoneNum;
}
- (UIImageView *)arrow {
if (_arrow == nil) {
_arrow = [[UIImageView alloc]init];
_arrow.image = [UIImage imageNamed:@"detail_arrow"];
}
return _arrow;
}
- (UILabel *)receiver {
if (_receiver == nil) {
_receiver = [[UILabel alloc]init];
_receiver.text = @"收货人";
_receiver.textColor = [UIColor lightGrayColor];
_receiver.font = [UIFont systemFontOfSize:14];
}
return _receiver;
}
- (UIImageView *)position {
if (_position == nil) {
_position = [[UIImageView alloc]init];
_position.image = [UIImage imageNamed:@"Detail_position"];
}
return _position;
}
将这些控件加在view上
- (void)setupUI {
[self addSubview:self.position];
[self.position mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self);
make.left.equalTo(self).offset(15);
make.height.equalTo(@20);
make.width.equalTo(@15);
}];
[self addSubview:self.arrow];
[self.arrow mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.position);
make.right.equalTo(self).offset(-15);
make.height.equalTo(@15);
make.width.equalTo(@10);
}];
//
[self addSubview:self.receiver];
[self.receiver mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.position.mas_right).offset(10);
make.top.equalTo(self).offset(10);
}];
[self addSubview:self.phoneNum];
[self.phoneNum mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.arrow.mas_left).offset(-10);
make.centerY.equalTo(self.receiver);
}];
[self addSubview:self.address];
[self.address mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.receiver);
make.top.equalTo(self.receiver.mas_bottom).offset(10);
make.right.equalTo(self.phoneNum);
}];
}
重写初始化方法
- (instancetype)initWithFrame:(CGRect)frame {
if (self == [super initWithFrame:frame]) {
[self setupUI];
[self addGes];
}
return self;
}
因为地址右侧有一个箭头,这里应该可以是点击的所以添加一个手势
UITapGestureRecognizer *tapRecognizerTop =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondToTapGesture:)];
tapRecognizerTop.numberOfTapsRequired = 1;
[self addGestureRecognizer:tapRecognizerTop];
实现手势的单击方法
- (void)respondToTapGesture:(UITapGestureRecognizer *)ges {
}
在GHDetailHeaderView.h中写代理协议
@class GHDetailHeaderView;
@protocol GHDetailHeaderViewDelegate <NSObject>
@optional
- (void)headerView: (GHDetailHeaderView *)headerView;
@end
增加一个代理属性
@property (nonatomic , weak) id <GHDetailHeaderViewDelegate>delegate;
在单击手势里相应代理方法
- (void)respondToTapGesture:(UITapGestureRecognizer *)ges {
if (self.delegate && [self.delegate respondsToSelector:@selector(headerView:)]) {
[self.delegate headerView:self];
}
}
在控制器里创建tableView,同样是懒加载
@property (nonatomic , strong) UITableView *tableView;
- (UITableView *)tableView {
if (_tableView == nil) {
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height + 49) style:UITableViewStyleGrouped];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:[GHDetailViewCell class] forCellReuseIdentifier:@"GHDetailViewCell"];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
_tableView.backgroundColor = [UIColor clearColor];
_tableView.showsVerticalScrollIndicator = NO;
}
return _tableView;
}
添加到tableView到当前view
[self.view addSubview:self.tableView];
self.tableView.tableHeaderView = self.header;
现在效果就是这样
![](https://img.haomeiwen.com/i1419035/e9302c8af1c36eab.png)
接下来根据cell来构造数据,根据cell我制定了7种样式,在模型里声明一个枚举值,就是cellType
/// 商店
GHDetailsCellType_shop = 1,
/// 商品
GHDetailsCellType_goods ,
/// 输入数量
GHDetailsCellType_inputNums,
/// 配送方式
GHDetailsCellType_delivery,
/// 配送时间
GHDetailsCellType_time,
/// 运费险
GHDetailsCellType_insurance,
/// 留言
GHDetailsCellType_message
@property (nonatomic , assign) GHDetailsCellType cellType;
这个模型还要标题,详情,行高
@property (nonatomic , copy) NSString *title;
@property (nonatomic , copy) NSString *details;
@property (nonatomic , assign) NSInteger cellHeight;
定义一个方法来构造假数据
+ (NSMutableArray *)creatDetailsData;
实现构造方法
+ (NSMutableArray *)creatDetailsData {
NSArray *titleArray = @[@"商店名称",@"11",@"购买数量",@"配送方式",@"配送时间",@"运费险",@"买家留言"];
NSArray *detailsArray = @[@"111",@"111",@"",@"快递免费",@"周五送达",@"退货前可赔",@""];
NSArray *cellTypeArray = @[
@(GHDetailsCellType_shop),
/// 商品
@(GHDetailsCellType_goods),
/// 输入数量
@(GHDetailsCellType_inputNums),
/// 配送方式
@(GHDetailsCellType_delivery),
/// 配送时间
@(GHDetailsCellType_time),
/// 运费险
@(GHDetailsCellType_insurance),
/// 留言
@(GHDetailsCellType_message)];
NSMutableArray *array = [NSMutableArray array];
for (NSInteger index = 0; index < 7; index++) {
GHDetailsModel *model = [[GHDetailsModel alloc]init];
model.title = titleArray[index];
model.details = detailsArray[index];
NSNumber *typeNum = cellTypeArray[index];
model.cellType = (GHDetailsCellType)typeNum.integerValue;
if (model.cellType == GHDetailsCellType_goods) {
model.cellHeight = 90;
} else {
model.cellHeight = 44;
}
[array addObject:model];
}
return array;
}
在控制器引入模型,把数据取出来,因为订单可能是有多个,我这里就不创建另外一个数组了,直接拿原来可以实现一样的效果只不过数据是一模一样的.
- (void)creatData {
[self.dataArray addObject: [GHDetailsModel creatDetailsData]];
[self.dataArray addObject: [GHDetailsModel creatDetailsData]];
}
拿到数据之后就来实现tableView的代理方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.dataArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *array = self.dataArray[section];
return array.count;
}
给cell赋值
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *array = self.dataArray[indexPath.section];
GHDetailsModel *model = array[indexPath.row];
GHDetailViewCell *cell = [GHDetailViewCell initCellWithTableView:tableView];
cell.model = model;
return cell;
}
现在效果是这样的
![](https://img.haomeiwen.com/i1419035/e13635d5ad1667fb.png)
就差底下的部分里其实这里有两种方案一种就是做成tableView的footer一种就是做成sectionFooter, footer不太好刷新所以这里做成sectionFooter,在sectionFooter里我定义一个tableView,也是分组的
懒加载等代码就不在说明了和之前是一样的,创建好这个sectionFooter之后再代理方法里添加他
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if (section == self.dataArray.count - 1) {
GHDetailFooterView *footer = [[GHDetailFooterView alloc]initWithFrame:CGRectMake(0, 0, 0, 226 + 20)];
NSMutableArray *dataArray = [NSMutableArray array];
NSMutableArray *temp = [GHDetailsModel creatDetailsFooterData];
[dataArray addObject:@[temp.firstObject]];
[temp removeObjectAtIndex:0];
[dataArray addObject:temp];
footer.dataArray = dataArray;
return footer;
} else {
return nil;
}
}
这里我同样构造了footer的假数组
+ (NSMutableArray *)creatDetailsFooterData {
NSMutableArray *array = [NSMutableArray array];
NSArray *titleArray = @[@"优惠券",@"商品金额",@"立减",@"运费"];
NSArray *detailsArray = @[@"无可用",@"100",@"100",@"100"];
for (NSInteger index = 0; index < 4; index++) {
GHDetailsModel *model = [[GHDetailsModel alloc]init];
model.title = titleArray[index];
model.details = detailsArray[index];
model.cellHeight = 44;
[array addObject:model];
}
return array;
}
这个时候运行是看不到效果的,还要在tebleView的代理方法里给高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if (section == self.dataArray.count -1) {
return 246;
} else {
return 0.01;
}
}
最终效果
Untitled.gif
网友评论