iOS 优秀实践程序员iOS Developer

iOS 标签Tag列表的实现

2016-03-12  本文已影响2720人  王隆帅

前言

1、之前项目中会有一些标签列表来显示某些特性或要求,如下图(代码实现后的效果):

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及工具类,等有时间我会陆续将这些分享给大家,希望能帮到有需求的人,共勉!


我的公众号二维码
上一篇 下一篇

猜你喜欢

热点阅读