美文网首页iOS记录
iOS UITableViewCell+UIStackView

iOS UITableViewCell+UIStackView

作者: money_ac9e | 来源:发表于2021-08-12 11:36 被阅读0次

    前言

    目前最常用的展示数据的控件是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:这是我同事写的,被我盗用了....

    相关文章

      网友评论

        本文标题:iOS UITableViewCell+UIStackView

        本文链接:https://www.haomeiwen.com/subject/rsxlbltx.html