iOS 多个标签动态排列

这里写图片描述

如上图所示:

自定义标签,自行排列,可控制边距,行距,列举,实现整齐的自由排列,话不多说,看代码

//.m主页面
#import "ViewController.h"
#import "TagsFrame.h"

@interface ViewController ()
{
    TagsFrame *_frame;
    NSArray *_tagsArray;
}
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    _tagsArray = @[@"全部",@"哈哈哈哈哈哈",@"的点点滴滴多多",@"他啦啦啦啦啦啦",@"发哈几个",@"鞥UNv",@"麓山国际后悔过",@"lllllldaffff",@"lalalalall",@"啦啦啦啦啦啦",@"喵喵吗喵毛",@"囖囖囖囖大家开发及囖囖咯",@"安安",@"对对对",@"错",@"初音MIKU",@"ANIMENZ哈哈哈哈哈哈哈",@"PENBEAT",@"OP",@"ILEM",@"原创",@"作业用BGM",@"打到车才",@"大卫反反复复",@"BGM",@"LAUNCHPAD"];

    _frame = [[TagsFrame alloc] init];
    _frame.tagsArray = _tagsArray;
    [self createSubView];
}

- (void)createSubView
{
    UIView *backView = [[UIView alloc] init];
    backView.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64);
    [self.view addSubview:backView];

    for (NSInteger i=0; i< _tagsArray.count; i++) {
        UIButton *tagsBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [tagsBtn setTitle:_tagsArray[i] forState:UIControlStateNormal];
        [tagsBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        tagsBtn.titleLabel.font = TagsTitleFont;
        tagsBtn.backgroundColor = [UIColor whiteColor];
        tagsBtn.layer.borderWidth = 1;
        tagsBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
        tagsBtn.layer.cornerRadius = 4;
        tagsBtn.layer.masksToBounds = YES;
        tagsBtn.frame = CGRectFromString(_frame.tagsFrames[i]);
        [backView addSubview:tagsBtn];
    }
}
@end
//标签frame封装
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#define WIDTH [UIScreen mainScreen].bounds.size.width
#define HEIGHT [UIScreen mainScreen].bounds.size.height

#define TagsTitleFont [UIFont systemFontOfSize:13]

@interface TagsFrame : NSObject
/** 标签名字数组 */
@property (nonatomic, strong) NSArray *tagsArray;
/** 标签frame数组 */
@property (nonatomic, strong) NSMutableArray *tagsFrames;
/** 全部标签的高度 */
@property (nonatomic, assign) CGFloat tagsHeight;
/** 标签间距 default is 10*/
@property (nonatomic, assign) CGFloat tagsMargin;
/** 标签行间距 default is 10*/
@property (nonatomic, assign) CGFloat tagsLineSpacing;
/** 标签最小内边距 default is 10*/
@property (nonatomic, assign) CGFloat tagsMinPadding;

@end
//  计算多个标签的位置
//  标签根据文字自适应宽度
//  每行超过的宽度平均分配给每个标签
//  每行标签左右对其

#import "TagsFrame.h"

@implementation TagsFrame

- (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;
        if (i < tagsArray.count-1) {
            nextWidth = [self sizeWithText:tagsArray[i+1] font:TagsTitleFont].width + _tagsMinPadding * 2;
        }
        CGFloat nextBtnX = btnX + btnW + _tagsMargin;
        // 如果下一个按钮,标签最右边则换行
        if ((nextBtnX + nextWidth) > (WIDTH - _tagsMargin)) {
            // 计算超过的宽度
            moreWidth = WIDTH - nextBtnX;
            [lastIndexs addObject:[NSNumber numberWithInteger:i]];
            [moreWidths addObject:[NSNumber numberWithFloat:moreWidth]];
            btnX = _tagsMargin;
        }else{
            btnX += (btnW + _tagsMargin);
        }
        // 如果是最后一个且数组中没有,则把最后一个加入数组
        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;

    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];
        }
        // 从数组中截取每一行的数组
        NSArray *newArr = [tagsArray subarrayWithRange:NSMakeRange(location, length)];
        location = lastIndex + 1;
        averageW = [moreWidths[i] floatValue]/newArr.count;
        CGFloat tagX = _tagsMargin;
        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);
            [_tagsFrames addObject:NSStringFromCGRect(btnF)];
            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];
}
@end
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值