iOS 标签Tag列表的实现
2016-03-12 本文已影响2720人
王隆帅
前言
1、之前项目中会有一些标签列表来显示某些特性或要求,如下图(代码实现后的效果):
![](https://img.haomeiwen.com/i1686195/6044e55d6ce7f638.png)
2、期间也是浏览了好多其他的第三方,但是可能是没找到好的方法去寻找吧,没有找到一个合适的,况且又不是特别复杂的东西,所以就自己写了一套,但是注意因为我们项目中使用的是RAC+Mansory,所以想要使用的话需要引入这两个库=_=。
3、自己写的时候考虑的不是太多,中心思想是ViewModel做定制需求,View通过ViewModel来实现定制化UI,其他更多的是逻辑上的排版,所以不做更多赘述,自己体会YoY 。
View布局
LSLabelTextView.h的实现
//
// LSLabelTextView.h
// RenCheRen
//
// Created by 王隆帅 on 15/12/30.
// Copyright © 2015年 王隆帅. All rights reserved.
//
#import "YCView.h"
@interface LSLabelTextView : YCView
@end
LSLabelTextView.m的实现
//
// LSLabelTextView.m
// RenCheRen
//
// Created by 王隆帅 on 15/12/30.
// Copyright © 2015年 王隆帅. All rights reserved.
//
#import "LSLabelTextView.h"
#import "LSLabelTextViewModel.h"
@interface LSLabelTextView ()
@property (nonatomic, strong) LSLabelTextViewModel *viewModel;
@end
@implementation LSLabelTextView {
MASConstraint *_toLeftBtnMasConstraint;
MASConstraint *_toTopBtnMasonstraint;
MASConstraint *_toLeftSelfMasConstraint;
MASConstraint *_toTopSelfMasonstraint;
}
- (instancetype)initWithViewModel:(id<YCViewModelProtocol>)viewModel {
self.viewModel = (LSLabelTextViewModel *)viewModel;
return [super initWithViewModel:viewModel];
}
- (void)yc_bindViewModel {
@weakify(self);
[[RACObserve(self, viewModel.dataArray) distinctUntilChanged] subscribeNext:^(id x) {
@strongify(self);
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
if (self.viewModel.dataArray.count <= 0) {
__weak UIView *weakNullView;
UIView *nullView = [[UIView alloc] init];
weakNullView = nullView;
[self addSubview:weakNullView];
WS(weakSelf)
[weakNullView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.right.left.bottom.equalTo(weakSelf);
make.height.equalTo(weakSelf.viewModel.nullHeight);
}];
return;
}
NSInteger lineNum = 1;
CGFloat allWidth = 0;
__weak UIButton *lastBtn;
for (int i = 0; i < self.viewModel.dataArray.count; i++) {
NSString *string = [self.viewModel.dataArray stringWithIndex:i];
__weak UIButton *weakBtn = [self ls_getBtnWithString:string];
[self addSubview:weakBtn];
CGSize size = [string widthWithHeight:20 andFont:self.viewModel.textFontNum];
CGFloat needFloat = size.width < self.viewModel.miniWidth ? self.viewModel.miniWidth : size.width;
if (lastBtn) {
WS(weakSelf)
[weakBtn mas_makeConstraints:^(MASConstraintMaker *make) {
_toLeftBtnMasConstraint = make.left.equalTo(lastBtn.mas_right).offset(weakSelf.viewModel.labelHorizontalSpace);
[_toLeftBtnMasConstraint activate];
_toTopBtnMasonstraint = make.top.equalTo(lastBtn.mas_bottom).offset(weakSelf.viewModel.labelVerticalSpace);
[_toTopBtnMasonstraint deactivate];
_toLeftSelfMasConstraint = make.left.equalTo(weakSelf.viewModel.leftToViewEdge);
_toTopSelfMasonstraint = make.top.equalTo(lastBtn);
make.size.equalTo(CGSizeMake(needFloat + 20, weakSelf.viewModel.labelHeight));
}];
if (allWidth + self.viewModel.labelHorizontalSpace + needFloat + 20 + self.viewModel.rightToViewEdge > self.viewModel.allWidth) {
[_toLeftSelfMasConstraint activate];
[_toLeftBtnMasConstraint deactivate];
[_toTopBtnMasonstraint activate];
[_toTopSelfMasonstraint deactivate];
lineNum ++;
allWidth = self.viewModel.leftToViewEdge + needFloat + 20;
} else {
[_toLeftSelfMasConstraint deactivate];
[_toLeftBtnMasConstraint activate];
[_toTopBtnMasonstraint deactivate];
[_toTopSelfMasonstraint activate];
allWidth = allWidth + self.viewModel.labelHorizontalSpace + needFloat + 20;
}
} else {
WS(weakSelf)
[weakBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(weakSelf.viewModel.leftToViewEdge);
make.size.equalTo(CGSizeMake(needFloat + 20, weakSelf.viewModel.labelHeight));
make.top.equalTo(weakSelf.viewModel.topToViewEdge);
}];
allWidth = allWidth + self.viewModel.leftToViewEdge + needFloat + 20;
}
lastBtn = weakBtn;
}
WS(weakSlef)
[lastBtn mas_updateConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(weakSlef.viewModel.bottomToViewEdge);
}];
}];
}
- (UIButton *)ls_getBtnWithString:(NSString *)string {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.layer.borderWidth = 0.5;
btn.layer.borderColor = self.viewModel.borderColor.CGColor;
[btn setTitleColor:self.viewModel.titleColor forState:UIControlStateNormal];
btn.backgroundColor = self.viewModel.backgroundColor;
btn.layer.masksToBounds = YES;
btn.layer.cornerRadius = self.viewModel.cornerRadius;
btn.titleLabel.font = YC_YAHEI_FONT(self.viewModel.textFontNum);
[btn setTitle:string forState:UIControlStateNormal];
btn.ls_typeString = string;
return btn;
}
@end
ViewModel适配
LSLabelTextViewModel.h的实现
//
// LSLabelTextViewModel.h
// RenCheRen
//
// Created by 王隆帅 on 15/12/30.
// Copyright © 2015年 王隆帅. All rights reserved.
//
#import "YCViewModel.h"
@interface LSLabelTextViewModel : YCViewModel
/**
* 标签数组
*/
@property (nonatomic, strong) NSMutableArray *dataArray;
/**
* 总的宽度
*/
@property (nonatomic, assign) CGFloat allWidth;
/**
* 没有标签时的高度
*/
@property (nonatomic, assign) CGFloat nullHeight;
/**
* 文字字体大小
*/
@property (nonatomic, assign) CGFloat textFontNum;
/**
* 取得标签为空的时候,标签最小长度
*/
@property (nonatomic, assign) CGFloat miniWidth;
/**
* 标签高度
*/
@property (nonatomic, assign) CGFloat labelHeight;
/**
* 最左侧标签距离View的边缘的宽度
*/
@property (nonatomic, assign) CGFloat leftToViewEdge;
/**
* 最右侧标签距离View的边缘的宽度
*/
@property (nonatomic, assign) CGFloat rightToViewEdge;
/**
* 最上侧标签距离View的边缘的宽度
*/
@property (nonatomic, assign) CGFloat topToViewEdge;
/**
* 最下侧标签距离View的边缘的宽度
*/
@property (nonatomic, assign) CGFloat bottomToViewEdge;
/**
* 横向标签之间的宽度
*/
@property (nonatomic, assign) CGFloat labelHorizontalSpace;
/**
* 纵向标签之间的宽度
*/
@property (nonatomic, assign) CGFloat labelVerticalSpace;
/**
* label(btn) 的相关属性
*/
@property (nonatomic, assign) CGFloat borderWidth;
@property (nonatomic, strong) UIColor *borderColor;
@property (nonatomic, strong) UIColor *titleColor;
@property (nonatomic, strong) UIColor *backgroundColor;
@property (nonatomic, assign) CGFloat cornerRadius;
@end
LSLabelTextViewModel.m的实现
//
// LSLabelTextViewModel.m
// RenCheRen
//
// Created by 王隆帅 on 15/12/30.
// Copyright © 2015年 王隆帅. All rights reserved.
//
#import "LSLabelTextViewModel.h"
@implementation LSLabelTextViewModel
- (NSMutableArray *)dataArray {
if (!_dataArray) {
_dataArray = [[NSMutableArray alloc] init];
}
return _dataArray;
}
@end
四、结语
在自己在工作过程中也总结了不少技术点、封装了一些Category及工具类,等有时间我会陆续将这些分享给大家,希望能帮到有需求的人,共勉!
![](https://img.haomeiwen.com/i1686195/aafb96c9a02eb284.jpg)