设计多选按钮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 == 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
需要注意的地方: