iOS 标签Tag列表的实现代码

前言

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

2、期间也是浏览了好多其他的第三方,但是可能是没找到好的方法去寻找吧,没有找到一个合适的,况且又不是特别复杂的东西,所以就自己写了一套,但是注意因为我们项目中使用的是RAC+Mansory,所以想要使用的话需要引入这两个库=_=。

3、自己写的时候考虑的不是太多,中心思想是ViewModel做定制需求,View通过ViewModel来实现定制化UI,其他更多的是逻辑上的排版,所以不做更多赘述,自己体会Y^o^Y 。

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS实现动态自适应标签

    先上效果图  设计要求 1.标签的宽度是按内容自适应的 2.一行显示的标签个数是动态的,放得下就放,放不下就换行 3.默认选中第一个 4.至少选中一个标签 实现思路 首先我们从这个效果上来看,这个标签是有选中和不选中状态,那我们首选的控件肯定就是用 UIButton来实现了. 这个小程度的重点就在于标签能自动换行,还是智能的,不是固定一行多少个那种,这个我们通过计算每个按钮实际宽度与屏幕的宽度进行比较就能判断是否需要换行了. 还有一点就是处理 至少选中一个标签的功能,我这里有一种方式,就是控制按

  • ios动态设置lbl文字标签的高度

    复制代码 代码如下: txtlbl.font = [UIFont boldSystemFontOfSize:14.0f];     txtlbl.numberOfLines = 0;  NSString *str = @"        阿方决定设立科技特网络离开电视剧分w额两个大陆高科技了了不见了日i倒计时离开我说老师肯德基弗兰克萨江东父老将费德勒说阿方决定设立科技特网络离开电视剧分w额两个大陆高科技了了不见了日i倒计时离开我立科说老师肯德基弗兰克萨江东父老将费德勒说";    CG

  • iOS仿微信添加标签效果(shape实现)

    一. 概述 可以说微信做的用户体验太棒了,可以做到老少皆宜,给个赞,我们也同时应该告诫自己,用户体验应该向微信看齐,微信就是我们的标杆,那我们今天也来仿一仿微信添加的标签功能.只能仿着做了,真是做不到微信的那种体验.甘拜下风. 我们上篇学习了shape属性的用法,那我们今天就用shape来做下微信的标签功能.先看一下效果. 我不仅用到了shape属性,还用到了翔哥的标签布局FlowLayout跟TagFlowLayout鸿洋的博客 二.效果图 三 .定义shape 添加标签 <?xml vers

  • iOS实现顶部标签式导航栏及下拉分类菜单

    本文实例为大家分享了iOS实现顶部标签式导航栏及下拉分类菜单的全部过程,供大家参考,具体内容如下 当内容及分类较多时,往往采用顶部标签式导航栏,例如网易新闻客户端的顶部分类导航,最近刚好有这样的应用场景,参考网络上一些demo,实现了这种导航效果,记录一些要点. 效果图(由于视频转GIF掉帧,滑动和下拉动画显得比较生硬,刚发现quickTime可以直接录制手机视频,推荐一下,很方便) 1.顶部标签式导航栏 (1)实现思路 其实就是在上下两个UIScrollView上做文章,实现联动选择切换的效果

  • iOS应用开发中UITabBarController标签栏控制器使用进阶

    做了这么长时间的ios开发了,最基本的UITabBarController和UINavigationController都用了好长时间了,总是改现成的代码,或者各种自定义控件的修改,用的都有些混乱了,呵呵.还是自己做个demo再复习一下吧,记录下来以备后续翻查. 一.UITabBarController和UINavigationController的联合使用 这种方法最常见,好像一般有tabbar都会有naviBar.一般使用, 1. 在appDelegate里面创建UITabBarContro

  • iOS 标签Tag列表的实现代码

    前言 1.之前项目中会有一些标签列表来显示某些特性或要求,如下图(代码实现后的效果): 2.期间也是浏览了好多其他的第三方,但是可能是没找到好的方法去寻找吧,没有找到一个合适的,况且又不是特别复杂的东西,所以就自己写了一套,但是注意因为我们项目中使用的是RAC+Mansory,所以想要使用的话需要引入这两个库=_=. 3.自己写的时候考虑的不是太多,中心思想是ViewModel做定制需求,View通过ViewModel来实现定制化UI,其他更多的是逻辑上的排版,所以不做更多赘述,自己体会Y^o^

  • IOS展开三级列表效果示例

    效果图如下: #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end #import "AppDelegate.h" #import "RootViewController.h" @interface AppDelegate

  • IOS 通过tag删除动态创建的UIButton

    IOS 通过tag删除动态创建的UIButton 动态创建 直接上代码 //开始按钮 let btnStart=UIButton() btnStart.tag=100 //重点在这里 btnStart.frame=CGRectMake(CGRectGetMidX(self.frame) / 2 + 25, CGRectGetMidY(self.frame) / 2 + 30, 100, 40) btnStart.setTitle("开始",forState: UIControlStat

  • Android ItemDecoration 实现分组索引列表的示例代码

    本文介绍了Android ItemDecoration 实现分组索引列表的示例代码,分享给大家.具体如下: 先来看看效果: 我们要实现的效果主要涉及三个部分: 分组 GroupHeader 分割线 SideBar 前两个部分涉及到一个ItemDecoration类,也是我们接下来的重点,该类是RecyclerView的一个抽象静态内部类,主要作用就是给RecyclerView的ItemView绘制额外的装饰效果,例如给RecyclerView添加分割线. 使用ItemDecoration时需要继

  • java接收ios文件上传的示例代码

    本文实例为大家分享了java如何接收ios文件上传的具体代码,供大家参考,具体内容如下 ios Multipart/form-data POST请求java后台spring接口一直出错,搞了两天,终于解决了,积累下来 package com.xx.controller; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator

  • js动态添加带圆圈序号列表的实例代码

    1.先在body里面添加ul标签 <!-- 无序列表 --> <ul id="list"> </ul> 2.通过js获取到id等于list的标签 定义一个空字符串用来连接增加的标签,并展示出来 如图的js代码展示的是前三个颜色不同,余下的颜色相同的圆圈序号 function autoAddList(){ var oUl = document.getElementById('list'); // var arr = ['湖南','广西','新疆','上

  • iOS实现联系人列表功能

    本文实例为大家分享了iOS实现联系人列表功能的具体代码,供大家参考,具体内容如下 按照顺序排列联系人列表,需要引入一些工具(详见demo): 主要部分代码: #import "LinkMan.h" #import "LinkmanCell.h" #import "LinkmanSelectCell.h" #import "pinyin.h" #import "ChineseString.h" @interf

  • 使用JavaScript制作待办事项列表的示例代码

    目录 JavaScript待办事项列表 如何制作JavaScript待办事项列表 第 1 步: 项目的基本结构 第 2 步: 使用 HTML 创建一个输入位置 第 3 步: 制作查看 Todo 文本的列表 第 4 步: 使用 JavaScript 激活待办事项列表 JavaScript 解释 JavaScript待办事项列表 我在此处展示了有关如何使用 JavaScript创建待办事项列表 HTML 的完整信息和教程.我借助HTML 和 CSS来设计它.在 JavaScript 的帮助下实现.

  • C#实现创建标签PDF文件的示例代码

    目录 关于“标签PDF文件(Tagged PDF) 关于“标签(Tag) PDF标签的用处及意义 如何创建标签PDF文件 关于“标签PDF文件(Tagged PDF) 标签PDF文件包含描述文档结构和各种文档元素顺序的元数据,是一种包含后端提供的可访问标记,管理阅读顺序和文档内容表示的逻辑结构的PDF文件[1]. 关于“标签(Tag) PDF标签是通过屏幕阅读器等支持技术访问PDF文档内容的关键.PDF标记在层次结构或标记树(tag tree)中排列PDF内容[1]. 这里的标签是一种不可见的标

  • jQuery ul标签下拉菜单演示代码

    这是菜单的内容,用ul标签实现菜单: 复制代码 代码如下: <div id="menu"> <ul> <li><a href="">菜单一</a> <ul> <li><a href="">子菜单1</a></li> <li><a href="">子菜单2</a> <u

随机推荐