UI基础常用组件iOS大咖说

ios标签的自定义

2016-07-06  本文已影响871人  羊驼先生丶

先上图。

屏幕快照 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)
上一篇 下一篇

猜你喜欢

热点阅读