本文共 10258 字,大约阅读时间需要 34 分钟。
设计多选按钮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@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 == 0) { NSLog(@"没有一个元素可供选择"); return; } // 存储所有按钮中文本的宽度 for (int i = 0; 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 = 0; i < _titleArray.count; i++) { [self.allButtonsState addObject:@(NO)]; } // 选择按钮列表 if (self.chosenTitleArray) { for (int i = 0; i < self.chosenTitleArray.count; i++) { // 获取标题 NSString *title = self.chosenTitleArray[i]; // 找到匹配的就替换 for (int j = 0; j < _titleArray.count; j++) { if ([_titleArray[j] isEqualToString:title]) { [self.allButtonsState replaceObjectAtIndex:j withObject:@(YES)]; break; } } } } // 创建出控件 CGFloat tmpXpositon = 0; for (int i = 0; i < _titleArray.count; i++) { CGFloat viewGap = (self.gap == 0 ? 5 : self.gap); if (i == 0) { tmpXpositon += 0; } else { tmpXpositon += [_buttonWidthArray[i - 1] floatValue] + self.buttonOffset; } // 临时的view,用于存储button UIView *tmpView = [[UIView alloc] initWithFrame:CGRectMake(0 + i*viewGap + tmpXpositon, 0, [_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 = 1; // 显示图片 } else { imageView.alpha = 0; // 隐藏图片 } [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 <= 0 ? 1 : self.lineWidth); // 设置按钮边缘粗细 if (self.lineColor) { tmpButton.layer.borderColor = self.lineColor.CGColor; // 设定线条颜色 } if (self.cornerRadius > 0) { tmpButton.layer.cornerRadius = self.cornerRadius; // 设定圆角 } [tmpButton addTarget:self action:@selector(buttonsEvent:) forControlEvents:UIControlEventTouchUpInside]; // 计算总长度(最后一次循环) if (_titleArray.count - 1 == 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 = 0.f; }]; } else { UIImageView *tmpView = (UIImageView *)[[button superview] viewWithTag:UIIMAGEVIEW + index]; [UIView animateWithDuration:0.15 animations:^{ tmpView.alpha = 1.f; }]; }}/** * 计算 * * @param string 文本 * @param font 字体 * * @return 宽度 */- (CGFloat)string:(NSString *)string widthWithLabelFont:(UIFont *)font { CGFloat retHeight = 0; if (string.length == 0) { retHeight = 0; } else { // 字体 NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:18.f]}; if (font) { attribute = @{NSFontAttributeName: font}; } // 尺寸 CGSize retSize = [string boundingRectWithSize:CGSizeMake(MAXFLOAT, 0) 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(10, 0, 300, 25)]; chooseView.center = self.view.center; chooseView.buttonOffset = 20; chooseView.gap = 7.f; chooseView.cornerRadius = 3.f; chooseView.buttonFont = [UIFont systemFontOfSize:14.f]; chooseView.normalStateButtonTitleColor = [UIColor grayColor]; chooseView.highlightedStateButtonTitleColor = [UIColor cyanColor]; chooseView.lineColor = [UIColor grayColor]; chooseView.selectedImage = [UIImage imageNamed:@"selected"]; chooseView.offsetY = -5; chooseView.offsetX = 10.f; chooseView.titleArray = @[@"女武神", @"瓦尔基里", @"YouXianMing", @"小苹果", @"梦醒时分"]; chooseView.chosenTitleArray = @[@"YouXianMing"]; [chooseView createListChooseView]; [self.view addSubview:chooseView];}@end
需要注意的地方: