zoukankan      html  css  js  c++  java
  • 设计多选按钮ListChooseView

    设计多选按钮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

    需要注意的地方:

  • 相关阅读:
    node.js 安装后怎么打开 node.js 命令框
    thinkPHP5 where多条件查询
    网站title中的图标
    第一次写博客
    Solution to copy paste not working in Remote Desktop
    The operation could not be completed. (Microsoft.Dynamics.BusinessConnectorNet)
    The package failed to load due to error 0xC0011008
    VS2013常用快捷键
    微软Dynamics AX的三层架构
    怎样在TFS(Team Foundation Server)中链接团队项目
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/4180651.html
Copyright © 2011-2022 走看看