前言
目前最常用的展示数据的控件是UITableView,不管是列表还是详情都很常用
列表是一样的cell 这里没有什么好说的
主要说下详情的页面使用UITableView处理
详情页面的难点是可能会有多个cell,不同的样式,不同的种类
如下图
image.png
这三个不同的cell 怎么才能更简单处理呢?
思路
可以使用UITableViewCell+UIStackView 的思路处理
UIStackView 可以展示不同的控件 并且可自动布局
我们可以根据需要 在上面放置 btn、image、label等 满足我们的需要
以此想法 完全可以使用一个cell 满足我们显示三个不同的cell的需求
实现
按照上面的想法 我们可以根据枚举值来给UIStackView添加不同的控件
主要可分为5类
/// 文字
DHTableViewCellExtensibleModeText = 1 << 0,
/// 站位
DHTableViewCellExtensibleModeSpace = 1 << 1,
/// 图标
DHTableViewCellExtensibleModeImage = 1 << 2,
/// 输入
DHTableViewCellExtensibleModeInput = 1 << 3,
/// 按钮
DHTableViewCellExtensibleModeButton = 1 << 4,
为方便维护 我们单独创建一个对象 来保存需要显示在UIStackView上的控件的信息
在创建一个分类 UITableViewCell+DHExtensible 来展示控件
这里罗列下 UITableViewCell+DHExtensible 文件中的代码
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class DHTableViewCellExtensible;
@interface UITableViewCell (DHExtensible)
@property (strong, nonatomic) UIStackView *extensibleStackView;
- (void)setExtensibleViews:(NSArray<DHTableViewCellExtensible *>*)views;
@end
#import "UITableViewCell+DHExtensible.h"
#import "DHTableViewCellExtensible.h"
static NSString *extensibleStackViewKey = @"extensibleStackViewKey";
@implementation UITableViewCell (DHExtensible)
- (void)setExtensibleViews:(NSArray<DHTableViewCellExtensible *> *)views
{
[self.extensibleStackView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[views enumerateObjectsUsingBlock:^(DHTableViewCellExtensible * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
UIView *view = obj.tableViewCellExtensibleView;
CGSize size = [view sizeThatFits:CGSizeZero];
if (obj.size.width != 0 || obj.size.height != 0) {
size = obj.size;
UIView *superView = [[UIView alloc] init];
superView.backgroundColor = UIColor.clearColor;
[self.extensibleStackView addArrangedSubview:superView];
[superView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(size.width);
make.height.mas_equalTo(size.height);
}];
if (size.height == 0) {
size.height = self.extensibleStackView.height_ext;
}
[superView addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(size.width);
make.height.mas_equalTo(size.height);
make.center.mas_equalTo(superView.center);
}];
} else {
if (size.height == 0) {
size.height = self.extensibleStackView.height_ext;
}
[self.extensibleStackView addArrangedSubview:view];
if ([view isKindOfClass:[UIImageView class]]) {
view.contentMode = UIViewContentModeScaleAspectFit;
}
if (!obj.widthFull) {
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(size.width);
make.height.mas_equalTo(size.height);
}];
}else
{
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(size.height);
}];
}
}
}];
}
#pragma mark - setter && getter
- (void)setExtensibleStackView:(UIStackView *)extensibleStackView
{
objc_setAssociatedObject(self, &extensibleStackViewKey, extensibleStackView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIStackView *)extensibleStackView
{
UIStackView *stackView = objc_getAssociatedObject(self, &extensibleStackViewKey);
if (!stackView) {
stackView = [[UIStackView alloc] init];
stackView.spacing = 4.0;
stackView.axis = UILayoutConstraintAxisHorizontal;
[self addSubview:stackView];
[stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(5);
make.right.mas_equalTo(self).offset(-15);
make.height.mas_equalTo(35.5f);
}];
self.extensibleStackView = stackView;
}
return stackView;
}
@end
对于 UIStackView 我们需要注意 有addArrangedSubview和addSubview 两种方法添加子控件
对于这两者的区别 我认为addArrangedSubview 会遵守UIStackView里面的协议,即按照需要填充大小 addSubview 则会根据我们的需要显示在固定为位置上
所以这里就有个问题 我们既需要控件填充位置 又需要根据我们的需要展示在固定位置上
这里添加两个view来实现此功能 superView填充位置 需要的view显示在固定位置
ps:这是我同事写的,被我盗用了....
网友评论