美文网首页iOS常用iOS学习专题
iOS 写一个自动布局高度的标签格子视图

iOS 写一个自动布局高度的标签格子视图

作者: Yuency | 来源:发表于2020-08-27 17:13 被阅读0次

    前言:

    总能碰到这样的东西,如果要使用UICollectionView来做,有种杀鸡焉用牛刀的感觉,而且,还得自己去算宽度,个人感觉不是很好。以前做这个东西,都是使用计算frame的方法,现在项目里都是用Masonry,所以就用这个框架,写了这个控件,这里记录了写这玩意的宽度,高度,位置排放,的代码思路。

    效果图:


    标签视图.gif

    代码地址:https://github.com/gityuency/ObjectiveCTools
    示例代码类名 【FloatScrollViewController】

    代码如下:

    注意:代码中使用到了 Masonry 框架来进行自动布局,请在使用时,添加到项目中。

    YXTagsView.h

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface YXTagsView : UIView
    
    /// 初始化
    - (instancetype)init;
    /// 行间距
    @property (nonatomic) CGFloat spacingRow;
    /// 列间距
    @property (nonatomic) CGFloat spacingColumn;
    /// 内容缩进
    @property (nonatomic) UIEdgeInsets contentInset;
    /// 加载小格子
    @property (nonatomic, strong) NSArray <NSString *> *arrayTags;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    YXTagsView.m

    #import "YXTagsView.h"
    #import <Masonry/Masonry.h>
    
    #pragma mark - 小格子
    @interface PaddingLabel : UILabel
    @property (nonatomic) UIEdgeInsets insets;
    @end
    
    @implementation PaddingLabel
    - (instancetype)init {
        self = [super init];
        if (self) {
            _insets = UIEdgeInsetsMake(10, 20, 10, 20);
            self.font = [UIFont boldSystemFontOfSize:14];
            self.textColor = [UIColor whiteColor];
            self.backgroundColor = [UIColor redColor];
            self.clipsToBounds = YES;
            self.textAlignment = NSTextAlignmentCenter;
        }
        return self;
    }
    - (void)drawTextInRect:(CGRect)rect {
        [super drawTextInRect:UIEdgeInsetsInsetRect(rect, _insets)];
    }
    - (CGSize)intrinsicContentSize {
        CGSize superContentSize = [super intrinsicContentSize];
        CGFloat width = superContentSize.width + _insets.left + _insets.right;
        CGFloat heigth = superContentSize.height + _insets.top + _insets.bottom;
        return CGSizeMake(width, heigth);
    }
    @end
    
    
    #pragma mark - 视图
    @interface YXTagsView ()
    
    @property (nonatomic, strong) UIView *containerView;
    
    @end
    
    @implementation YXTagsView
    
    - (instancetype)init {
        self = [super init];
        if (self) {
            _spacingRow = 10;
            _spacingColumn = 10;
            _containerView = [[UIView alloc] init];
            [self addSubview:_containerView];
            [_containerView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.edges.equalTo(self);
            }];
        }
        return self;
    }
    
    - (void)setArrayTags:(NSArray<NSString *> *)arrayTags {
        _arrayTags = arrayTags;
        [self setNeedsLayout];
        [self layoutIfNeeded];
    }
    
    - (void)setContentInset:(UIEdgeInsets)contentInset {
        _contentInset = contentInset;
        [self setNeedsLayout];
        [self layoutIfNeeded];
    }
    
    - (void)setSpacingRow:(CGFloat)spacingRow {
        _spacingRow = spacingRow;
        [self setNeedsLayout];
        [self layoutIfNeeded];
    }
    
    - (void)setSpacingColumn:(CGFloat)spacingColumn {
        _spacingColumn = spacingColumn;
        [self setNeedsLayout];
        [self layoutIfNeeded];
    }
    
    ///开始布局格子
    - (void)layoutChildItems {
        
        //先把原来的数据移除掉
        for (UIView *v in self.containerView.subviews) {
            [v removeFromSuperview];
        }
        
        self.containerView.backgroundColor = [UIColor brownColor];
        [self.containerView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(@(_contentInset));
        }];
        
        //宽度
        CGFloat containerWidth = self.containerView.frame.size.width;
        //如果宽度小于等于0,表示这个视图还没有完成约束,拿不到宽度,也就无法继续做下一步的小格子宽度排布计算
        if (containerWidth <= 0) {
            NSLog(@"❗️❗️❗️❗️ YXTagsView 视图没有宽度,暂不能进行排布!");
            return;
        }
        
        //累计宽度
        CGFloat maxX = 0;
        //记录上一个格子
        PaddingLabel *beforeLabel;
        //记录上一个底部约束
        __block MASConstraint *bottomCons = nil;
        
        //添加新的数据
        for (NSInteger i = 0; i < _arrayTags.count; i ++) {
            
            PaddingLabel *label = [[PaddingLabel alloc] init];
            label.text = _arrayTags[i];
            
            [_containerView addSubview:label];
            //先做一下约束,然后拿到宽度
            [label mas_makeConstraints:^(MASConstraintMaker *make) {
                make.top.left.equalTo(_containerView);
            }];
            [label setNeedsLayout];
            [label layoutIfNeeded];
            
            CGFloat labelWidth = label.frame.size.width;
            CGFloat labelHeight = label.frame.size.height;
            label.layer.cornerRadius = labelHeight / 2.0;
            
            if ((maxX + labelWidth + _spacingRow) > containerWidth) { //换到下一行的第一个
                [bottomCons deactivate];
                [label mas_remakeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(_containerView);
                    make.top.equalTo(beforeLabel.mas_bottom).offset(_spacingColumn);
                    bottomCons = make.bottom.equalTo(_containerView);
                }];
                maxX = labelWidth;
            } else { //继续在这一行
                if (beforeLabel) { //同一行 第2,3,4...个
                    [bottomCons deactivate];
                    [label mas_remakeConstraints:^(MASConstraintMaker *make) {
                        make.left.equalTo(beforeLabel.mas_right).offset(_spacingRow);
                        make.top.equalTo(beforeLabel);
                        bottomCons = make.bottom.equalTo(_containerView);
                    }];
                    maxX += labelWidth + _spacingRow;
                } else { //第一行第一个
                    [label mas_remakeConstraints:^(MASConstraintMaker *make) {
                        make.left.equalTo(_containerView);
                        make.top.equalTo(_containerView);
                        bottomCons = make.bottom.equalTo(_containerView);
                    }];
                    maxX = labelWidth;
                }
            }
            beforeLabel = label;
        }
    }
    
    - (void)layoutSubviews {
        [super layoutSubviews];
        [self layoutChildItems];
    }
    
    @end
    
    

    在ViewController里测试:

    #import "ViewController.h"
    #import <Masonry/Masonry.h>
    #import "YXTagsView.h"
    
    @interface ViewController ()
    
    @property (nonatomic, strong) YXTagsView *tagsView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.tagsView = [[YXTagsView alloc] init];
        _tagsView.arrayTags = @[@"可以", @"在", @"添加到", @"父视图之前", @"设置", @"数据"];
        _tagsView.backgroundColor = [UIColor purpleColor];
        [self.view addSubview:_tagsView];
        [_tagsView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(self.view).offset(20);
            make.right.equalTo(self.view).offset(-20);
            make.top.equalTo(self.view).offset(100); 
            //不用给高度,高度由内部的tags个数自动撑开,只需要设置好这个视图的宽度即可。
        }];
        _tagsView.arrayTags = @[@"也可以", @"在", @"添加到", @"父视图", @"之后", @"设置", @"数据"];
    }
    
    - (IBAction)action1:(id)sender {
        NSInteger a = arc4random_uniform(30);
        NSInteger b = arc4random_uniform(30);
        NSInteger c = arc4random_uniform(30);
        NSInteger d = arc4random_uniform(30);
        self.tagsView.contentInset = UIEdgeInsetsMake(a, b, c, d);
    }
    
    - (IBAction)action2:(id)sender {
        NSArray *aaaaaa = @[@"愿", @"天", @"堂", @"没", @"有", @"bug", @"从", @"此", @"不", @"写", @"代", @"码"];
        NSMutableArray *tagArray = [NSMutableArray array];
        NSInteger ttttttt = arc4random_uniform(20);
        for (NSInteger j = 0; j < ttttttt; j ++) {
            NSMutableString *s = [[NSMutableString alloc] init];
            NSInteger suijishu = arc4random_uniform(5) + 1; //文字长度随机数
            NSMutableArray *mmmmm = [NSMutableArray arrayWithArray:aaaaaa];
            for (NSInteger i = 0; i < suijishu; i ++) {
                int shuzuchuangdu = (int)mmmmm.count;
                NSInteger k = arc4random_uniform(shuzuchuangdu);
                [s appendFormat:@"%@", mmmmm[k]];
                [mmmmm removeObjectAtIndex:k];
            }
            [tagArray addObject:s];
        }
        NSLog(@"%@", tagArray);
        self.tagsView.arrayTags = tagArray;
    }
    
    - (IBAction)action3:(id)sender {
        self.tagsView.spacingRow = arc4random_uniform(30);
        self.tagsView.spacingColumn = arc4random_uniform(30);
    }
    
    @end
    

    结语

    写几个破代码真的烦死了。

    相关文章

      网友评论

        本文标题:iOS 写一个自动布局高度的标签格子视图

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