最近项目有个需求,能够动态的展示一组数据标签,于是自己动手做了一个自定义的view,此自定义View暂时只是为了实现功能,其他的扩展功能以后有需要再添加。
首先是MViewTextList.h文件
//
// MViewTagList.h
// mall
//
// Created by zyz on 16/3/21.
// Copyright © 2016年 codeagod. All rights reserved.
// 文字tag展示,支持多选,支持单选
#import <UIKit/UIKit.h>
@class MViewTextList;
@protocol MViewTextListDelegate <NSObject>
/**
* 代理方法,用户选择某个tag按钮
*/
- (void)viewTextListDidSelectTagViewTextList:(MViewTextList *)viewTextList selectBtn:(UIButton *)selectBtn selectDatas:(NSArray *)selectDatas;
/**
* 代理方法,用户取消某个tag按钮
*/
- (void)viewTextListDidCancelTagViewTextList:(MViewTextList *)viewTextList cancelBtn:(UIButton *)cancelBtn selectDatas:(NSArray *)selectDatas;
@end
@interface MViewTextList : UIView
#pragma :标签的数据集合
@property (nonatomic,strong) NSArray *datas;
#pragma :选中的数据集合
@property (nonatomic,strong) NSMutableArray *datasSelect;
#pragma :是否单选
@property (nonatomic,assign) BOOL singleSelect;
#pragma :代理
@property (nonatomic,weak) id<MViewTextListDelegate> delegate;
#pragma :字体的大小,如果没有设置会有一个默认的数值
@property (nonatomic,assign) CGFloat textSize;
#pragma :内边距,如果没有设置会有一个默认的数值
@property (nonatomic,assign) CGFloat spaceIn;
#pragma :外边距,如果没有设置会有一个默认的数值
@property (nonatomic,assign) CGFloat spaceOut;
#pragma :普通的背景颜色,如果没有设置,会有一个默认的圆角背景
@property (nonatomic,strong) UIColor *colorNormalBackground;
#pragma :选中的背景颜色,如果没有设置,会有一个默认的圆角背景
@property (nonatomic,strong) UIColor *colorSelectedBackground;
#pragma :普通的字体颜色,如果没有设置,会有一个默认的字体颜色
@property (nonatomic,strong) UIColor *colorNormalText;
#pragma :选中的字体颜色,如果没有设置,会有一个默认的字体颜色
@property (nonatomic,strong) UIColor *colorSelectedText;
@end
其次,是MViewTextList.m文件内容
//
// MViewTagList.m
// mall
//
// Created by zyz on 16/3/21.
// Copyright © 2016年 codeagod. All rights reserved.
//
#import "MViewTextList.h"
#define kDefaultInSpace 10
#define kDefaultOutSpace 10
#define kDefaultTextSize 15
#define kDefaultImageNormalColor ([UIColor grayColor])
#define kDefaultImageSelectedColor ([UIColor whiteColor])
#define kDefaultTextNormalColor ([UIColor whiteColor])
#define kDefaultTextSelectedColor ([UIColor grayColor])
@interface MViewTextList ()
#pragma :选中的标签按钮,单选模式下有效
@property (nonatomic,weak) UIButton *btnSelect;
@end
@implementation MViewTextList
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (NSMutableArray *)datasSelect
{
if (_datasSelect == nil) {
_datasSelect = [[NSMutableArray alloc] init];
}
return _datasSelect;
}
- (void)setDatas:(NSArray *)datas
{
CGFloat width = self.width;
for (int i = 0;i< datas.count ;i++)
{
NSString *strTag = datas[i];
CGSize realSize = [strTag sizeWithFont:[UIFont systemFontOfSize:self.textSize] maxSize:CGSizeMake(kScreenWidth - 2 * self.spaceOut, CGFLOAT_MAX)];
if (self.width > 0) {
if (i == 0) {
UIButton *btn = [self createButtonWithTitle:strTag];
//设置布局
btn.frame = CGRectMake(self.spaceOut, self.spaceOut, realSize.width + 2 * self.spaceIn, realSize.height + 2 * self.spaceIn);
//设置背景
[self setBtnBackGroundWithBtn:btn];
[self addSubview:btn];
//重新计算高度
self.height = btn.height + 2 * self.spaceOut;
}else{
CGFloat leaveWidth = width - CGRectGetMaxX([self.subviews lastObject].frame);
if ((realSize.width + self.spaceOut + 2 * self.spaceIn) > leaveWidth) {
/**
* 下一行显示
*/
UIButton *btn = [self createButtonWithTitle:strTag];
btn.frame = CGRectMake(self.spaceOut, CGRectGetMaxY([self.subviews lastObject].frame) + self.spaceOut, realSize.width + 2 * self.spaceIn, realSize.height + 2 * self.spaceIn);
//设置背景
[self setBtnBackGroundWithBtn:btn];
[self addSubview:btn];
//重新计算高度
self.height = CGRectGetMaxY([self.subviews lastObject].frame) + self.spaceOut;
}else{
/**
* 同一行显示
*/
UIButton *btn = [self createButtonWithTitle:strTag];
btn.frame = CGRectMake(CGRectGetMaxX([self.subviews lastObject].frame) + self.spaceOut, [self.subviews lastObject].y, realSize.width + 2 * self.spaceIn, realSize.height + 2 * self.spaceIn);
//设置背景
[self setBtnBackGroundWithBtn:btn];
[self addSubview:btn];
}
}
}
}
}
/**
* 设置按钮的背景颜色
*/
- (void)setBtnBackGroundWithBtn:(UIButton *)btn
{
//设置默认状态背景
if (self.colorNormalBackground == nil) {
[btn setBackgroundImage:[UIImage imageFromColor:kDefaultImageNormalColor frame:btn.frame] forState:UIControlStateNormal];
}else{
[btn setBackgroundImage:[UIImage imageFromColor:self.colorNormalBackground frame:btn.frame] forState:UIControlStateNormal];
}
//设置选中状态背景
if (self.colorSelectedBackground == nil) {
[btn setBackgroundImage:[UIImage imageFromColor:kDefaultImageSelectedColor frame:btn.frame] forState:UIControlStateSelected];
}else{
[btn setBackgroundImage:[UIImage imageFromColor:self.colorSelectedBackground frame:btn.frame] forState:UIControlStateSelected];
}
}
- (void) setBtnTextColorWithBtn:(UIButton *)btn
{
//设置普通模式下的字体颜色
if (self.colorNormalText == nil) {
[btn setTitleColor:kDefaultTextNormalColor forState:UIControlStateNormal];
}else{
[btn setTitleColor:self.colorNormalText forState:UIControlStateNormal];
}
//设置选中模式下的字体颜色
if (self.colorSelectedText == nil) {
[btn setTitleColor:kDefaultTextSelectedColor forState:UIControlStateSelected];
}else{
[btn setTitleColor:self.colorSelectedText forState:UIControlStateSelected];
}
}
/**
* 创建一个UIButton
*/
- (UIButton *)createButtonWithTitle:(NSString *)title
{
UIButton *btn = [[UIButton alloc] init];
//
btn.layer.masksToBounds = YES;
//设置圆角
btn.layer.cornerRadius = 4;
//设置字体
btn.titleLabel.font = [UIFont systemFontOfSize:self.textSize];
//设置字体颜色
[self setBtnTextColorWithBtn:btn];
//设置普通模式下的标题
[btn setTitle:title forState:UIControlStateNormal];
//设置按钮的点击响应对象的方法
[btn addTarget:self action:@selector(didTagBtn:) forControlEvents:UIControlEventTouchUpInside];
return btn;
}
- (void)didTagBtn:(UIButton *)btn
{
if (self.singleSelect) {
if (!btn.selected) {
//取消之前的选中选项
if (self.btnSelect != nil) {
self.btnSelect.selected = NO;
}
//将当前点击的按钮赋给选中按钮
self.btnSelect = btn;
//设置选中的按钮为选中状态
self.btnSelect.selected = YES;
//移除数据集合里面旧数据
[self.datasSelect removeAllObjects];
//增加新数据
[self.datasSelect addObject:self.btnSelect.currentTitle];
//响应代理
if ([self.delegate respondsToSelector:@selector(viewTextListDidSelectTagViewTextList:selectBtn:selectDatas:)]) {
[self.delegate viewTextListDidSelectTagViewTextList:self selectBtn:btn selectDatas:self.datasSelect];
}
}
}else{
if (btn.selected) {
/**
* 取消选中效果
*/
//获取点击的按钮的标题
NSString *curTitle = btn.currentTitle;
//如果该标题包含在选中数据集合中,则移除
if ([self.datasSelect containsObject:curTitle]) {
[self.datasSelect removeObject:curTitle];
}
//响应代理
btn.selected = NO;
if ([self.delegate respondsToSelector:@selector(viewTextListDidCancelTagViewTextList:cancelBtn:selectDatas:)]) {
[self.delegate viewTextListDidCancelTagViewTextList:self cancelBtn:btn selectDatas:self.datasSelect];
}
}else{
/**
* 选中效果
*/
btn.selected = YES;
//获取点击的按钮的标题
NSString *curTitle = btn.currentTitle;
//如果该标题不包含在选中数据集合中,则添加进去
if (![self.datasSelect containsObject:curTitle]) {
[self.datasSelect addObject:curTitle];
}
//响应代理
if ([self.delegate respondsToSelector:@selector(viewTextListDidSelectTagViewTextList:selectBtn:selectDatas:)]) {
[self.delegate viewTextListDidSelectTagViewTextList:self selectBtn:btn selectDatas:self.datasSelect];
}
}
}
}
- (CGFloat)spaceIn
{
if (_spaceIn == 0 || _spaceIn < 0) {
_spaceIn = kDefaultInSpace;
}
return _spaceIn;
}
- (CGFloat)spaceOut
{
if (_spaceOut == 0 || _spaceOut < 0) {
_spaceOut = kDefaultOutSpace;
}
return _spaceOut;
}
- (CGFloat)textSize
{
if (_textSize == 0 || _textSize < 0) {
_textSize = kDefaultTextSize;
}
return _textSize;
}
@end
其次,是调用代码
MViewTextList *viewTextListTag = [[MViewTextList alloc] init];
viewTextListTag.delegate = self;
viewTextListTag.frame = CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 100);
viewTextListTag.spaceIn = 10;//设置内边距,注意此步骤必须在setDatas之前
viewTextListTag.spaceOut = 10;//设置外边距,注意此步骤必须在setDatas之前
// viewTextListTag.singleSelect = YES;//设置是否单选
viewTextListTag.colorNormalBackground = [UIColor whiteColor];
viewTextListTag.colorSelectedBackground = [UIColor purpleColor];
viewTextListTag.colorNormalText = [UIColor purpleColor];
viewTextListTag.colorSelectedText = [UIColor whiteColor];
//设置数据集合,最好在最后进行设置
viewTextListTag.datas =@[@"红",@"橙",@"紫",@"青",@"靛",@"蓝",@"白",@"黑",@"肤色",@"阳光少女",@"魅惑经典",@"都市时尚"];
[self.view addSubview:viewTextListTag];
另外,还涉及到一个计算字符串实际大小的方法
创建字符串的扩展类NSString(Extension),之后添加方法
/**
* 计算文本占用的宽高
*
* @param font 显示的字体
* @param maxSize 最大的显示范围
*
* @return 占用的宽高
*/
- (CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize
{
NSDictionary *dict = @{NSFontAttributeName: font};
CGSize textSize = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil].size;
return textSize;
}
下面是效果图
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DN3kDNzIDNxEjMyMDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)