zoukankan      html  css  js  c++  java
  • button自适应宽度 并根据屏幕宽自动换行排列

    这是一个封装好的类TagListView, 

    1. 只需要调用两个方法 设置宽度,间距,边距 并赋给它需要显示的字符串数组; 

    2. 遵循tagListView的协议, 并实现返回buttonView的方法.

    即可展现.

    这里我用了SDAutoLayout, 一个三方布局, 用cocopod安装一下就好;

    一下是具体的实现代码 带 注释解释

    //  TagListView.h 该类的.h文件
    
    #import <UIKit/UIKit.h>
    @protocol TagListViewDelegate<NSObject>
    @required
    - (UIButton *)setItemBtnView;   //必须实现方法:返回buttonView
    @optional
    - (void)clickWithBtn:(UIButton *)btn idx:(NSInteger)idx; //点击button触发方法
    @end
    
    typedef void(^ReturnClickBtnArr)(NSArray *btnArr);  // 返回已选中的按钮数组
    
    @interface TagListView : UIView
    
    @property(nonatomic, strong) UIButton *itemBtn;
    @property(nonatomic, assign) NSUInteger maxSelectedTags;    // 多选值
    @property(nonatomic, strong) NSMutableArray *selectedTitles;    //已选中的按钮标题数组
    @property(nonatomic, weak) id <TagListViewDelegate> delegate;
    
    #pragma mark - 设置宽度 间距 边距
    - (void)setWid:(CGFloat)wid btnTitlePadding_X:(CGFloat)horizontailX btnTitlePadding_Y:(CGFloat)vertailY marginX:(CGFloat)marginX marginY:(CGFloat)marginY itemHeight:(CGFloat)height;
    
    #pragma mark - 设置字符串数组 (该方法必须在setWid...方法后执行)
    - (void)setTagViewWithTitles:(NSArray *)titleArr;
    
    - (NSArray *)getAllSubBtns;
    @end
    //  TagListView.m 该类的.m文件
    
    #import "TagListView.h"
    #import "UIView+SDAutoLayout.h"
    #define kHorizontalX 7
    #define kVerticalY 3
    #define kMarginY 10
    #define kMarginX 10
    
    @implementation TagListView {
        CGFloat _horizontailX;  // btn的左右间距
        CGFloat _vertailY;  // btn的上下间距
        CGFloat _marginX;   // tagView的左右边距
        CGFloat _marginY;   // tagVIew的上下边距
        CGFloat _wid;       // tagView的宽度
        CGFloat _itemHeight;    // btn的高度
        NSArray *_titleArray;   // 需要展示的字符串数组
    }
    
    - (instancetype)init {
        if (self = [super init]) {
            _horizontailX = kHorizontalX;
            _vertailY = kVerticalY;
            _marginX = kMarginY;
            _marginY = kMarginX;
            _wid = 0;
            _maxSelectedTags = 3; //default
            _selectedTitles = [NSMutableArray array];
        }
        return self;
    }
    
    #pragma mark - 设置宽度 间距 边距
    - (void)setWid:(CGFloat)wid btnTitlePadding_X:(CGFloat)horizontailX btnTitlePadding_Y:(CGFloat)vertailY marginX:(CGFloat)marginX marginY:(CGFloat)marginY itemHeight:(CGFloat)height {
        if (wid) {
            _wid = wid;
        }
        if (horizontailX) {
            _horizontailX = horizontailX;
        }
        if (vertailY) {
            _vertailY = vertailY;
        }
        if (marginX) {
            _marginX = marginX;
        }
        if (marginY) {
            _marginY = marginY;
        }
        if (height) {
            _itemHeight = height;
        }
    }
    
    #pragma mark - 设置字符串数组 (该方法必须在setWid...方法后执行)
    - (void)setTagViewWithTitles:(NSArray *)titleArr {
        _titleArray = [titleArr copy];
        
        // 清除所有子视图
        while (self.subviews.count) {
            UIView *child = self.subviews.lastObject;
            [child removeFromSuperview];
        }
        
        // 若未指定宽度 就 获得当前视图宽度
        if (_wid == 0) {
            [self updateLayout];
            _wid = self.width;
        }
        
        __block int totalHeight = 0;
        __block CGRect previousFrame = CGRectMake(0, 0, 0, 0);
        __block CGFloat height = 0;
        
        // 循环title数组
        [titleArr enumerateObjectsUsingBlock:^(NSString *title, NSUInteger idx, BOOL * _Nonnull stop) {
            UIButton *tag = [self.delegate setItemBtnView];
            [tag setTitle:title forState:UIControlStateNormal];
            [tag addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside];
            tag.tag = idx;
            
            // 设置已选中title的选中状态
            if ([self.selectedTitles containsObject:title]) {
                tag.selected = YES;
            } else {
                tag.selected = NO;
            }
            
            // 1. 计算size
            // 获得title字体对应的size
            NSDictionary *attrs = @{NSFontAttributeName : tag.titleLabel.font};
            CGSize Size_str = [title sizeWithAttributes:attrs];
            
            // 给size加上 上下边距
            Size_str.width += _horizontailX * 2;
            if (_itemHeight) {
                Size_str.height = _itemHeight;
            } else {
                Size_str.height += _vertailY * 2;
            }
            
            CGRect newRect = CGRectZero;
            newRect.size = Size_str;
            // 2. 计算origin
            if (CGRectGetMaxX(previousFrame) + Size_str.width + _marginX > _wid) { //换行
                newRect.origin = CGPointMake(0, CGRectGetMaxY(previousFrame) + _marginY);
                totalHeight += Size_str.height + _marginY;
            } else {    //未换行
                newRect.origin = CGPointMake((CGRectGetMaxX(previousFrame) == 0 ? 0 : CGRectGetMaxX(previousFrame) + _marginX), previousFrame.origin.y);
            }
            [tag setFrame:newRect];
            
            previousFrame = tag.frame;
            height = totalHeight + Size_str.height;
            
            [self addSubview:tag];
        }];
        
        self.sd_layout.heightIs(height);
    }
    
    - (NSArray *)getAllSubBtns {
        return  self.subviews;
    }
    
    #pragma mark - btn的点击方法
    - (void)onClick:(UIButton *)btn {
        // 1.如果超出最多选中数 则需把最先选中的删除
        if (!btn.selected && self.selectedTitles.count >= _maxSelectedTags){
            NSString *title = [self.selectedTitles objectAtIndex:0];
            NSUInteger firstSelectedIndex = [_titleArray indexOfObject:title];
            if (firstSelectedIndex != NSNotFound) {
                UIButton *selectedButton = [self.subviews objectAtIndex:firstSelectedIndex];
                selectedButton.selected = NO;
                [self.selectedTitles removeObjectAtIndex:0];
            }
        }
        long index = btn.tag;
        NSString *title = [_titleArray objectAtIndex:index];
        if (btn.selected) {     // 设置为未选中状态
            btn.selected = NO;
            [self.selectedTitles removeObject:title];
        } else {                // 设置为选中状态
            btn.selected = YES;
            [self.selectedTitles addObject:title];
        }
        // 若delegate包含该方法 则让其执行
        if ([self.delegate respondsToSelector:@selector(clickWithBtn:idx:)]) {
            [self.delegate clickWithBtn:btn idx:index];
        }
    }
    @end

    具体使用如下:

    //  ViewController.m
    
    #import "ViewController.h"
    #import "UIView+SDAutoLayout.h"
    #import "TagListView.h"
    
    #define kScreenWidth self.view.frame.size.width
    
    @interface ViewController ()<TagListViewDelegate>
    @property (nonatomic, strong)TagListView *tagListView;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.tagListView = [[TagListView alloc] init];
        self.tagListView.delegate = self;
        self.tagListView.backgroundColor = [UIColor cyanColor];
        self.tagListView.maxSelectedTags = 3;
        [self.view addSubview:self.tagListView];
        self.tagListView.sd_layout.topSpaceToView(self.view, 50).leftSpaceToView(self.view, 16).rightSpaceToView(self.view, 16);
        // 设置宽度 间距 边距
        [self.tagListView setWid:(kScreenWidth - 20) btnTitlePadding_X:20 btnTitlePadding_Y:20 marginX:20 marginY:20 itemHeight:20];
        // 设置需要显示的字符串数组
        [self.tagListView setTagViewWithTitles:@[@"周一", @"周二", @"周三", @"周四", @"周五", @"礼拜六", @"礼拜天", @"一月", @"二月", @"三月", @"四月", @"五月", @"六月", @"七月", @"八月", @"九月", @"十月", @"十一月", @"十二月", @"春天", @"夏天", @"秋天", @"冬天", @"张三", @"李四", @"王五"]];
    }
    
    #pragma mark - TagListViewDelegate
    // 必须实现的协议方法 返回buttonView
    - (UIButton *)setItemBtnView {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [btn setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
        btn.layer.borderWidth = 0.4;
        btn.layer.cornerRadius = 2;
        btn.layer.borderColor = [UIColor grayColor].CGColor;
        return btn;
    }
    
    @end
  • 相关阅读:
    迷宫最短路问题
    回溯算法
    解题报告:poj1321 棋盘问题
    矩阵、分数、点、线类
    判断图像中有多少行文本(开发中)
    图形-回行扫描函数
    贝叶斯分类器
    js解析数学运算公式
    用postcss给less加上webkit前缀
    node创建文件夹
  • 原文地址:https://www.cnblogs.com/moxiaoyan33/p/6132425.html
Copyright © 2011-2022 走看看