ios标签的自定义

先上图。

屏幕快照 2016-07-06 下午5.42.54.png

对该视图的封装

#import <UIKit/UIKit.h>
typedef void(^TagListViewOnTagClick)(NSUInteger index, NSString *tag);

/// 标签样式风格
typedef NS_ENUM(NSInteger, TagListViewStyle) {
    /// 标准大小
    TagListViewStyleStd,
    /// 大的
    TagListViewStyleBig,
};

@interface searchTagListView : UIView
+ (CGFloat)heightWithTags:(NSArray<NSString *> *)tags style:(TagListViewStyle)style;

/// 标签整体内容上间隔。默认0
@property (nonatomic, assign) CGFloat contentTopMargin;

/// 标签数据
@property (nonatomic, copy) NSArray<NSString *> *tags;

- (instancetype)initWithStyle:(TagListViewStyle)style;

/// 用户点击了某个标签
- (void)onTagClick:(TagListViewOnTagClick)block;
@end

#import "searchTagListView.h"
@interface searchTagListView ()
@property (nonatomic, strong) NSMutableArray<UIButton *> *tagButtonList;

@property (nonatomic, assign) TagListViewStyle style;
@property (nonatomic, copy) TagListViewOnTagClick onTagClickBlock;
@end

static CGFloat const kContentLeftRightMargin = 10;
static CGFloat const kTagHeight_std = 25;
static CGFloat const kTagHeight_big = 30;
static CGFloat const kTagSpacing = 15;
static CGFloat const kButtonTitleLeftRightMargin_std = 10;
static CGFloat const kButtonTitleLeftRightMargin_big = 8;

#define kTagFont_std     [UIFont fanZhengLanTingXHFontWithSize:11]
#define kTagFont_big     [UIFont fanZhengLanTingXHFontWithSize:14]
@implementation searchTagListView
/**
 *  计算标签视图需要的高度
 *
 *  @param tags          标签列表
 *  @param tagItemHandle 处理回调,通知外面这个Tag的显示信息
 *
 *  @return Tags在UI上的高度。
 */
+ (CGFloat)_heightWithTags:(NSArray<NSString *> *)tags style:(TagListViewStyle)style tagItemHandle:(void(^)(NSUInteger index, NSString *tagName, CGSize tagSize, BOOL needWrap))tagItemHandle {
    __block CGFloat tagsHeight = 0;
    if (tags && (tags.count > 0)) {
        UIFont *font = (style == TagListViewStyleStd ? kTagFont_std : kTagFont_big);
        CGFloat titleLeftRightMargin = (style == TagListViewStyleStd ? kButtonTitleLeftRightMargin_std : kButtonTitleLeftRightMargin_big);
        CGFloat tagHeight = (style == TagListViewStyleStd ? kTagHeight_std : kTagHeight_big);
        tagsHeight += tagHeight;
        
        CGFloat tagsContentWdith = SCREEN_WIDTH - kContentLeftRightMargin * 2;
        __block CGFloat currentRowWidth = tagsContentWdith;
        [tags enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            CGFloat tagWidth = [obj boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil].size.width + titleLeftRightMargin * 2 + 3;
            BOOL needWrap = NO;
            if (tagWidth > currentRowWidth && currentRowWidth != tagsContentWdith) {
                // 换行
                tagsHeight += kTagSpacing + tagHeight;
                currentRowWidth = tagsContentWdith;
                needWrap = YES;
            }
            GCBlockInvoke(tagItemHandle, idx, obj, CGSizeMake(MIN(tagWidth, tagsContentWdith), tagHeight), needWrap);
            currentRowWidth -= (tagWidth + kTagSpacing);
        }];
    }
    return tagsHeight;
}

+ (CGFloat)heightWithTags:(NSArray<NSString *> *)tags style:(TagListViewStyle)style {
    return [self _heightWithTags:tags style:style tagItemHandle:nil];
}

- (instancetype)init {
    if (self = [super init]) {
        self.contentTopMargin = 0;
        self.tagButtonList = [NSMutableArray array];
        self.style = TagListViewStyleStd;
    }
    return self;
}

- (instancetype)initWithStyle:(TagListViewStyle)style {
    if (self = [super init]) {
        self.contentTopMargin = 0;
        self.tagButtonList = [NSMutableArray array];
        self.style = style;
    }
    return self;
}

#pragma mark - public methods

- (void)setTags:(NSArray<NSString *> *)tags {
    _tags = [tags copy];
    [self _reloadButtonList];
}

- (void)onTagClick:(TagListViewOnTagClick)block {
    self.onTagClickBlock = block;
}

#pragma mark - private methods

- (UIButton *)_createButtonWithTagName:(NSString *)tagName {
    UIButton *button = [[UIButton alloc] init];
    button.titleLabel.font = (self.style == TagListViewStyleStd ? kTagFont_std : kTagFont_big);
    button.backgroundColor = k_COLOR_E7E7E7;
    CGFloat titleLeftRightMargin = (self.style == TagListViewStyleStd ? kButtonTitleLeftRightMargin_std : kButtonTitleLeftRightMargin_big);
    button.contentEdgeInsets = UIEdgeInsetsMake(0, titleLeftRightMargin, 0, titleLeftRightMargin);
    button.layer.cornerRadius = (self.style == TagListViewStyleStd ? kTagHeight_std : kTagHeight_big) * 0.5;
    button.layer.borderWidth = 0;
    [button setTitle:tagName forState:UIControlStateNormal];
    [button setTitleColor:k_COLOR_949494 forState:UIControlStateNormal];
    _weak(self);
    [button addControlEvents:UIControlEventTouchUpInside action:^(UIControl *control, NSSet *touches) {
        _strong_check(self);
        GCBlockInvoke(self.onTagClickBlock, control.tag, [(UIButton *)control titleForState:UIControlStateNormal]);
    }];
    return button;
}

- (void)_reloadButtonList {
    [self.tagButtonList enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [obj removeFromSuperview];
    }];
    [self.tagButtonList removeAllObjects];
    
    __block UIView *prevView = nil;
    [searchTagListView _heightWithTags:self.tags style:self.style tagItemHandle:^(NSUInteger index, NSString *tagName, CGSize tagSize, BOOL needWrap) {
        UIButton *btn = [self _createButtonWithTagName:tagName];
        [self addSubview:btn];
        [self.tagButtonList addObject:btn];
        
        UIButton *button = self.tagButtonList[index];
        [button mas_remakeConstraints:^(MASConstraintMaker *make) {
            if (prevView == nil) {
                make.left.equalTo(self).offset(kContentLeftRightMargin);
                make.top.equalTo(self).offset(self.contentTopMargin);
            }
            else if (needWrap) {
                make.left.equalTo(self).offset(kContentLeftRightMargin);
                make.top.equalTo(prevView.mas_bottom).offset(kTagSpacing);
            }
            else {
                make.left.equalTo(prevView.mas_right).offset(kTagSpacing);
                make.top.equalTo(prevView);
            }
            make.size.mas_equalTo(tagSize);
        }];
        prevView = button;
    }];
}

@end

*使用方法

 CGFloat height=[searchTagListView heightWithTags:_tagListView.tags style:TagListViewStyleStd];
    [self.hotTagLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.searchView.mas_bottom).offset(-12);
        make.left.equalTo(self.view);
        make.width.equalTo(@75);
        make.height.equalTo(@40);
        
    }];

-(searchTagListView *)tagListView{
    if (!_tagListView) {
        _weak(self);
        _tagListView=[[searchTagListView alloc] initWithStyle:TagListViewStyleStd];
     _tagListView.backgroundColor=self.view.backgroundColor;
        
        
        [_tagListView onTagClick:^(NSUInteger index, NSString *tag) {
             _strong_check(self);
            [self.searchTextField resignFirstResponder];
            self.keyword=tag;
           
            [self _loadDataWithIsLatest:YES];
        }];

    }
    return _tagListView;
}

使用方法截自项目,封装的类中含有项目中定义的宏替换掉就可以了
最后附上封装类中出现的宏
#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif

#define GCBlockInvoke(block, ...)   \
do {                            \
    if (block) {                \
        block(__VA_ARGS__);    \
    }                           \
} while(0)
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height

#define _weak(x)    __weak typeof(x) weak##x = x
#define _strong(x)  typeof(weak##x) x = weak##x
#define _strong_check(x, ...) typeof(weak##x) x = weak##x; if (!weak##x) return __VA_ARGS__;
#define RGB(r, g, b)        [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define k_COLOR_E7E7E7          RGB(221, 225, 224)
#define k_COLOR_949494          RGB(142, 151, 146)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容