iOS_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;

 

 

 

//  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

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章