美文网首页
ios中标签数组自适应

ios中标签数组自适应

作者: 叶小合 | 来源:发表于2018-01-26 11:18 被阅读47次

    在我们的开发中,经常会碰到关于多个标签的app界面,这个时候我需要对标签进行自适应的处理,我们先来看下自适应效果。

    屏幕快照 2018-01-26 上午11.06.00.png

    拿到这个界面,我们来整理一下思路

    1.计算每个标签的位置
    2.标签根据文字自适应宽度
    3.每行超过的宽度平均分配给每个标签
    4.每行标签左右对应
    

    敲黑板

    1.我们需要计算每行的最后一个标签的最大X坐标是否大于屏幕宽度和标准间距的差值。
    2.把正常数组分割成调整好的数组
    3.把每行换到下一行的标签宽度平均给当前行的标签
    

    主要代码如下:

    - (id)init
    {
        //初始化
        self = [super init];
        if (self) {
            _tagsFrames = [NSMutableArray array];
            _tagsMinPadding = 10;
            _tagsMargin = 10;
            _tagsLineSpacing = 10;
        }
        return self;
    }
    
    - (void)setTagsArray:(NSArray *)tagsArray
    {
        _tagsArray = tagsArray;
        
        CGFloat btnX = _tagsMargin;
        CGFloat btnW = 0;// 按钮宽度
        CGFloat nextWidth = 0;  // 下一个标签的宽度
        CGFloat moreWidth = 0;  // 每一行多出来的宽度
        // 每一行的最后一个tag的索引的数组
        NSMutableArray *lastIndexs = [NSMutableArray array];
        // 每一行多出来的宽度的数组
        NSMutableArray *moreWidths = [NSMutableArray array];
        
        for (NSInteger i=0; i<tagsArray.count; i++) {
            btnW = [self sizeWithText:tagsArray[i] font:TagsTitleFont].width + _tagsMinPadding * 2;// 宽度 = 文字的宽度+2倍的最小内边距
            // 计算下一个宽度
            if (i < tagsArray.count-1) {
                nextWidth = [self sizeWithText:tagsArray[i+1] font:TagsTitleFont].width + _tagsMinPadding * 2;
            }
            CGFloat nextBtnX = btnX + btnW + _tagsMargin; // 下一个标签 x的坐标 = 标签间距 + 按钮宽度 + 标签间距
            // 如果下一个(按钮x坐标+宽度) 大于 (屏幕宽度减去边距) 则这个标签需要换行
            if ((nextBtnX + nextWidth) > (WIDTH - _tagsMargin)) {
                // 计算正常情况下超过的宽度
                moreWidth = WIDTH - nextBtnX;
                [lastIndexs addObject:[NSNumber numberWithInteger:i]];// 加入 每一行的最后一个索引
                [moreWidths addObject:[NSNumber numberWithFloat:moreWidth]];//加入多余的宽度 【[] [] == 】拿到 == 的宽度
                btnX = _tagsMargin;
            }else{
                btnX += (btnW + _tagsMargin); // 计算 X 的坐标
            }
            // 如果是最后一个且数组中没有,则把最后一个加入数组
            if (i == tagsArray.count -1) {
                if (![lastIndexs containsObject:[NSNumber numberWithInteger:i]]) {
                    [lastIndexs addObject:[NSNumber numberWithInteger:i]];
                    [moreWidths addObject:[NSNumber numberWithFloat:0]];// 最后一个不用平均计算
                }
            }
        }
        
        NSInteger location = 0;  // 截取的位置
        NSInteger length = 0;    // 截取的长度
        CGFloat averageW = 0;    // 多出来的平均的宽度
        CGFloat tagW = 0;// 标签的宽度
        CGFloat tagH = 30;// 标签的高度
    //    lastIndexs 装有每一行的最后一个索引
        for (NSInteger i=0; i< lastIndexs.count; i++) {
            NSInteger lastIndex = [lastIndexs[i] integerValue];
            if (i == 0) {
                length = lastIndex + 1; //
            }else{
                length = [lastIndexs[i] integerValue]-[lastIndexs[i-1] integerValue];
            }
            // 最后拿到的length 是每一行的标签的个数
            // 从数组中截取每一行的数组
            NSArray *newArr = [tagsArray subarrayWithRange:NSMakeRange(location, length)];
            // newArr 装有分割好的每一行标签的数组
            NSLog(@"newArray = %@",newArr);
            location = lastIndex + 1; // 截取位置
        
            averageW = [moreWidths[i] floatValue]/newArr.count;//计算出每一行标签正常宽度多余的宽度的平均数,用来后面相加用的
            
            CGFloat tagX = _tagsMargin; // X坐标初始值等于 10
            CGFloat tagY = _tagsLineSpacing + (_tagsLineSpacing + tagH) * i;
            
            for (NSInteger j=0; j<newArr.count; j++) {
                tagW = [self sizeWithText:newArr[j] font:TagsTitleFont].width + _tagsMinPadding * 2 + averageW; // 拿到计算好的标签宽度
                CGRect btnF = CGRectMake(tagX, tagY, tagW, tagH);// 设置标签的frame
                [_tagsFrames addObject:NSStringFromCGRect(btnF)];// 把标签frame转换我字符串加入到_tagsFrames数组中去
                tagX += (tagW+_tagsMargin);
            }
        }
            _tagsHeight = (tagH + _tagsLineSpacing) * lastIndexs.count + _tagsLineSpacing; // 拿到
        
    }
    
    /**
     *  单行文本数据获取宽高
     *
     *  @param text 文本
     *  @param font 字体
     *
     *  @return 宽高
     */
    - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font
    {
        NSDictionary *attrs = @{NSFontAttributeName : font};
        return [text sizeWithAttributes:attrs]; // 计算字符串的宽和高
    }
    

    附上git地址:标签自适应

    相关文章

      网友评论

          本文标题:ios中标签数组自适应

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