设计多选按钮ListChooseView

答应某位女屌丝而写的控件,效果还不错,开源给大家^_^!

效果图:

源码:

//
// ListChooseView.h
// ScrollChooseButton
//
// http://www.jikexueyuan.com/course/397.html
// http://www.cnblogs.com/YouXianMing/
//
// Created by YouXianMing on 14/12/23.
// Copyright (c) 2014年 YouXianMing. All rights reserved.
// #import <UIKit/UIKit.h> @interface ListChooseView : UIView #pragma mark -
/**
* 按钮之间的间隙,不设置的话默认值为5
*/
@property (nonatomic, assign) CGFloat gap; /**
* 按钮值偏移量
*/
@property (nonatomic, assign) CGFloat buttonOffset; #pragma mark -
/**
* 标题数组
*/
@property (nonatomic, strong) NSArray *titleArray; /**
* 已经选择的标题的数组
*/
@property (nonatomic, strong) NSArray *chosenTitleArray; #pragma mark -
/**
* 按钮的字体
* 正常状态下的按钮色值(不设定则为白色)
* 高亮状态下的按钮色值(不设定则没有值)
* 按钮线条粗细(不设定默认值为1)
* 按钮线条颜色(不设定默认值为黑色)
* 按钮圆角
*/
@property (nonatomic, strong) UIFont *buttonFont;
@property (nonatomic, strong) UIColor *normalStateButtonTitleColor;
@property (nonatomic, strong) UIColor *highlightedStateButtonTitleColor;
@property (nonatomic, assign) CGFloat lineWidth;
@property (nonatomic, strong) UIColor *lineColor;
@property (nonatomic, assign) CGFloat cornerRadius; #pragma mark -
/**
* 选中状态下显示的图片
* 图片横线偏移量
* 图片纵向偏移量
*/
@property (nonatomic, strong) UIImage *selectedImage;
@property (nonatomic, assign) CGFloat offsetX;
@property (nonatomic, assign) CGFloat offsetY; #pragma mark - /**
* 选中的标题
*/
@property (nonatomic, strong, readonly) NSMutableArray *selectedIndex; /**
* 配置好所有参数后就创建出控件
*/
- (void)createListChooseView; @end
//
// ListChooseView.m
// ScrollChooseButton
//
// Created by YouXianMing on 14/12/23.
// Copyright (c) 2014年 YouXianMing. All rights reserved.
// #import "ListChooseView.h" typedef enum : NSUInteger {
UIBUTTON = 0x19871220, // [YouXingMing birthDay]
UIIMAGEVIEW = 0x88888888,
} EnumListChooseView; @interface ListChooseView () @property (nonatomic, assign) CGFloat buttonHeight; // 按钮的高度
@property (nonatomic, assign) CGFloat totalLength; // 总长度 @property (nonatomic, strong) UIScrollView *scrollView; // 用于滑动的scrollView
@property (nonatomic, strong) NSMutableArray *buttonWidthArray; // 存储所有按钮的宽度 @property (nonatomic, strong) NSMutableArray *allButtonsState; // 存储所有按钮点击状态
@property (nonatomic, strong) NSMutableArray *selectedIndex; @end @implementation ListChooseView - (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 添加scrollView
_scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
_scrollView.layer.masksToBounds = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
[self addSubview:_scrollView]; // 按钮高度
_buttonHeight = frame.size.height; // 存储所有按钮宽度
_buttonWidthArray = [NSMutableArray array];
}
return self;
} - (void)createListChooseView {
// 没有一个元素则直接返回
if (_titleArray.count == ) {
NSLog(@"没有一个元素可供选择");
return;
} // 存储所有按钮中文本的宽度
for (int i = ; i < _titleArray.count; i++) {
// 必须是字符串
if ([_titleArray[i] isKindOfClass:[NSString class]]) {
CGFloat buttonWidth = [self string:_titleArray[i] widthWithLabelFont:self.buttonFont];
[_buttonWidthArray addObject:@(buttonWidth)];
} else {
NSLog(@"有非字符串的东西混入");
return;
}
} // 所有按钮点击状态初始化(默认为NO,没有勾选)
self.allButtonsState = [NSMutableArray array];
for (int i = ; i < _titleArray.count; i++) {
[self.allButtonsState addObject:@(NO)];
} // 选择按钮列表
if (self.chosenTitleArray) {
for (int i = ; i < self.chosenTitleArray.count; i++) {
// 获取标题
NSString *title = self.chosenTitleArray[i]; // 找到匹配的就替换
for (int j = ; j < _titleArray.count; j++) {
if ([_titleArray[j] isEqualToString:title]) {
[self.allButtonsState replaceObjectAtIndex:j withObject:@(YES)];
break;
}
}
}
} // 创建出控件
CGFloat tmpXpositon = ;
for (int i = ; i < _titleArray.count; i++) { CGFloat viewGap = (self.gap == ? : self.gap); if (i == ) {
tmpXpositon += ;
} else {
tmpXpositon += [_buttonWidthArray[i - ] floatValue] + self.buttonOffset;
} // 临时的view,用于存储button
UIView *tmpView = [[UIView alloc] initWithFrame:CGRectMake( + i*viewGap + tmpXpositon,
,
[_buttonWidthArray[i] floatValue] + self.buttonOffset,
_buttonHeight)];
// 配置button
UIButton *tmpButton = [[UIButton alloc] initWithFrame:tmpView.bounds];
[tmpView addSubview:tmpButton]; // 按钮tag值
tmpButton.tag = UIBUTTON + i; if (self.selectedImage) { // 添加选中的图片
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.selectedImage]; CGRect rect = imageView.frame;
rect.origin.x = [_buttonWidthArray[i] floatValue] + self.offsetX;
rect.origin.y = self.offsetY;
imageView.frame = rect; imageView.tag = UIIMAGEVIEW + i;
if ([self.allButtonsState[i] boolValue] == YES) {
imageView.alpha = ; // 显示图片
} else {
imageView.alpha = ; // 隐藏图片
} [tmpView addSubview:imageView];
}
[tmpButton setTitle:_titleArray[i] forState:UIControlStateNormal]; // 设置标题
if (self.buttonFont) {
tmpButton.titleLabel.font = self.buttonFont; // 设置按钮字体
}
if (self.normalStateButtonTitleColor) {
[tmpButton setTitleColor:self.normalStateButtonTitleColor forState:UIControlStateNormal]; // 设置按钮正常标题颜色
}
if (self.highlightedStateButtonTitleColor) {
[tmpButton setTitleColor:self.highlightedStateButtonTitleColor forState:UIControlStateHighlighted]; // 高亮标题颜色
}
tmpButton.layer.borderWidth = (self.lineWidth <= ? : self.lineWidth); // 设置按钮边缘粗细
if (self.lineColor) {
tmpButton.layer.borderColor = self.lineColor.CGColor; // 设定线条颜色
}
if (self.cornerRadius > ) {
tmpButton.layer.cornerRadius = self.cornerRadius; // 设定圆角
} [tmpButton addTarget:self
action:@selector(buttonsEvent:)
forControlEvents:UIControlEventTouchUpInside]; // 计算总长度(最后一次循环)
if (_titleArray.count - == i) {
_totalLength = tmpView.frame.origin.x + [_buttonWidthArray[i] floatValue] + self.buttonOffset;
} [self.scrollView addSubview:tmpView];
} self.scrollView.contentSize = CGSizeMake(_totalLength, _buttonHeight);
} - (void)buttonsEvent:(UIButton *)button { // 第几个按钮
NSInteger index = button.tag - UIBUTTON;
BOOL selectedButtonState = [_allButtonsState[index] boolValue];
[_allButtonsState replaceObjectAtIndex:index withObject:@(!selectedButtonState)]; // 选择了几个按钮
self.selectedIndex = [NSMutableArray arrayWithArray:_allButtonsState]; // 更新按钮上面的图标
[self updateButtonImage:button index:index];
} - (void)updateButtonImage:(UIButton *)button index:(NSInteger)index{
if ([_allButtonsState[index] boolValue] == NO) {
UIImageView *tmpView = (UIImageView *)[[button superview] viewWithTag:UIIMAGEVIEW + index];
[UIView animateWithDuration:0.15 animations:^{
tmpView.alpha = .f;
}];
} else {
UIImageView *tmpView = (UIImageView *)[[button superview] viewWithTag:UIIMAGEVIEW + index];
[UIView animateWithDuration:0.15 animations:^{
tmpView.alpha = .f;
}];
}
} /**
* 计算
*
* @param string 文本
* @param font 字体
*
* @return 宽度
*/
- (CGFloat)string:(NSString *)string widthWithLabelFont:(UIFont *)font {
CGFloat retHeight = ; if (string.length == ) {
retHeight = ;
} else { // 字体
NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:.f]};
if (font) {
attribute = @{NSFontAttributeName: font};
} // 尺寸
CGSize retSize = [string boundingRectWithSize:CGSizeMake(MAXFLOAT, )
options:
NSStringDrawingTruncatesLastVisibleLine |
NSStringDrawingUsesLineFragmentOrigin |
NSStringDrawingUsesFontLeading
attributes:attribute
context:nil].size; retHeight = retSize.width;
} return retHeight;
} @end

使用时候的源码:

//
// ViewController.m
// ScrollChooseButton
//
// Created by YouXianMing on 14/12/23.
// Copyright (c) 2014年 YouXianMing. All rights reserved.
// #import "ViewController.h"
#import "ListChooseView.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; self.view.backgroundColor = [UIColor blackColor]; [self createListChooseView];
} - (void)createListChooseView {
ListChooseView *chooseView = [[ListChooseView alloc] initWithFrame:CGRectMake(, , , )];
chooseView.center = self.view.center;
chooseView.buttonOffset = ;
chooseView.gap = .f;
chooseView.cornerRadius = .f;
chooseView.buttonFont = [UIFont systemFontOfSize:.f];
chooseView.normalStateButtonTitleColor = [UIColor grayColor];
chooseView.highlightedStateButtonTitleColor = [UIColor cyanColor];
chooseView.lineColor = [UIColor grayColor];
chooseView.selectedImage = [UIImage imageNamed:@"selected"];
chooseView.offsetY = -;
chooseView.offsetX = .f;
chooseView.titleArray = @[@"女武神", @"瓦尔基里", @"YouXianMing", @"小苹果", @"梦醒时分"];
chooseView.chosenTitleArray = @[@"YouXianMing"];
[chooseView createListChooseView]; [self.view addSubview:chooseView];
} @end

需要注意的地方:

设计多选按钮ListChooseView的更多相关文章

  1. .NET开源工作流RoadFlow-表单设计-复选按钮组

    复选按钮组的设置与单选按钮组的设置相同,只是表现形式为:<input type="checkbox"/>

  2. 设计多选一按钮ChooseOnlyButton

    设计多选一按钮ChooseOnlyButton 效果: 源码: ChooseOnlyButton.h 与 ChooseOnlyButton.m // // ChooseOnlyButton.h // ...

  3. js动态获取子复选项并设计全选及提交

    在做项目的时候,会遇到根据父选项,动态的获取子选项,并列出多个复选框,提交时,把选中的合并成一个字符提交后台 本章将讲述如何通过js控制实现该操作: 1:设计父类别为radio,为每一个radio都加 ...

  4. Chapter 4. Button, Checkbutton, and Radiobutton Widgets 按钮,复选按钮,单选按钮

    Chapter 4. Button, Checkbutton, and Radiobutton Widgets   按钮,复选按钮,单选按钮 几乎所有的Perl/Tk 应用使用按钮以这样或者那样的方式 ...

  5. 单选按钮、复选按钮——axure线框图部件库介绍

    有时候发现这做事情坚持下来是一件很不容易的,写教程也一样,不过听到很多朋友对我说 这个全部是图片的教程 对他们入门帮助很多,我就想想 在坚持坚持把基础部分先完善了! 1. 简单的问卷调查: 您的性别? ...

  6. 《手把手教你》系列技巧篇(三十三)-java+ selenium自动化测试-单选和多选按钮操作-上篇(详解教程)

    1.简介 在实际自动化测试过程中,我们同样也避免不了会遇到单选和多选的测试,特别是调查问卷或者是答题系统中会经常碰到.因此宏哥在这里直接分享和介绍一下,希望小伙伴或者童鞋们在以后工作中遇到可以有所帮助 ...

  7. 《手把手教你》系列技巧篇(三十四)-java+ selenium自动化测试-单选和多选按钮操作-中篇(详解教程)

    1.简介 今天这一篇宏哥主要是讲解一下,如何使用list容器来遍历单选按钮.大致两部分内容:一部分是宏哥在本地弄的一个小demo,另一部分,宏哥是利用JQueryUI网站里的单选按钮进行实战. 2.d ...

  8. 《手把手教你》系列技巧篇(三十五)-java+ selenium自动化测试-单选和多选按钮操作-下篇(详解教程)

    1.简介 今天这一篇宏哥主要是讲解一下,如何使用list容器来遍历多选按钮.大致两部分内容:一部分是宏哥在本地弄的一个小demo,另一部分,宏哥是利用JQueryUI网站里的多选按钮进行实战. 2.d ...

  9. 《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)

    1.简介 前边几篇文章是宏哥自己在本地弄了一个单选和多选的demo,然后又找了网上相关联的例子给小伙伴或童鞋们演示了一下如何自动化测试,这一篇宏哥在网上找了一个问卷调查,给小伙伴或童鞋们来演示一下.上 ...

随机推荐

  1. [笔记] print函数进阶

      1.1print(values=None,sep='',end='\n',file=sys.stdout,flush=False) 参数: values:输出到控制台的string sep:设置输 ...

  2. Error : Weblogic Maven Plugin deployment WebLogic 12c

    Error : Weblogic Maven Plugin deployment i want to use weblogic-maven-plugin in my maven project in ...

  3. docker-compose管理daocker

    Docker-compose管理docker服务 1.安装docker-compose @首先确保服务器上已经安装docker环境,如果没有安装使用如下命令进行安装: # yum  -y  insta ...

  4. 单点登录(SSO)

    单点登录SSO(SingleSign-On)是身份管理中的一部分.SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后, ...

  5. jQuery+Ajax+PHP 制作简单的异步数据传输(测试用户名是否可用)

    实现基本异步数据传输,略去与数据库交换,先直接在PHP端判断:用户名为 user1 即为不可用, 测试时外加了 普遍的 “Loading..." 功能,此功能可直接在PHP中循环延时 for ...

  6. tomcat shutdown.sh结束不了,Could not contact localhost:8005

    使用./shutdown.sh关闭Tomcat,有时会关闭成功,有时会出现关闭错误; Jul 06, 2017 10:57:37 AM org.apache.catalina.startup.Cata ...

  7. The type org.springframework.jms.JmsException cannot be resolved报错解决

    在调用JmsTemplate的send方法时,一直报编译时异常.如下: 异常提示是无法解析org.SpringFrawork.jms.JmsException类型.如下: The type org.s ...

  8. HDU 1695 GCD 欧拉函数+容斥定理 || 莫比乌斯反演

    GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  9. 修改input被选中的默认样式

    input:focus{    outline: none;     border: 1px solid #fff; } 或者 input[type=text]:focus{   outline: n ...

  10. mybatis逆向文件

    一.mapper接口中的方法解析 mapper接口中的函数及方法 方法 功能说明 int countByExample(UserExample example) thorws SQLException ...