在开发中经常有需求要求创建一排按钮,下面我们就开发这一个组件,实现方式如下:
WHC_ButtonGroupView.h头文件如下:
//
// buttonGroupView.h
// buttonGroupView
//
// Created by 吴海超 on 14-6-6.
// Copyright (c) 2014年 buttonGroupView. All rights reserved.
//
/*
NOTE:获取组按钮默认创建实现方式如下:
+(WHC_ButtonGroupParam *)getDefaultParamWithTitleArr:(NSArray*)titleArr{
WHC_ButtonGroupParam * groupParam = [WHC_ButtonGroupParam new];
groupParam.normalBackColor = [UIColor grayColor];
groupParam.selectedBackColor = [UIColor blackColor];
groupParam.markColor = [UIColor clearColor];
groupParam.segmentLineY = 0.0;
groupParam.segmentLineColor = [UIColor blackColor];
groupParam.normalTextColor = [UIColor whiteColor];
groupParam.selectedTextColor = [UIColor grayColor];
groupParam.titles = titleArr;
groupParam.images = nil;
groupParam.scroll = NO;
groupParam.headLine = YES;
groupParam.footLine = YES;
groupParam.firstSegmentLine = YES;
groupParam.markViewDown = NO;
groupParam.fontSize = 16.0;
groupParam.markPading = 5.0;
return groupParam;
}
*/
#import <UIKit/UIKit.h>
@class WHC_ButtonGroupView;
@protocol WHC_ButtonGroupViewDelegate<NSObject>
@required
- (void)whcButtonGroup:(WHC_ButtonGroupView*)whcBtnView index:(NSInteger)index;
@end
@interface WHC_ButtonGroupParam : NSObject
@property BOOL scroll; //是否支持滚动
@property BOOL footLine; //是否显示底部线
@property BOOL headLine; //是否显示顶部线
@property BOOL markViewDown; //是否下标记
@property BOOL firstSegmentLine; //首部分割线
@property int currIndex; //当前下标
@property CGFloat fontSize; //字体大小
@property CGFloat btnHeight; //按钮高度
@property CGFloat btnWidth; //按钮宽度
@property CGFloat markPading; //游标和按钮的间隙
@property CGFloat segmentLineY; //分隔线Y坐标
@property CGFloat scrollWidth; //滚条宽度
@property UIColor *normalBackColor; //默认按钮背景颜色
@property UIColor *selectedBackColor; //选中按钮背景颜色
@property UIColor *normalTextColor; //默认状态按钮文字颜色
@property UIColor *selectedTextColor; //选中状态按钮文字颜色
@property UIColor *segmentLineColor; //分隔线颜色
@property UIColor *markColor; //移动游标颜色
@property NSArray *titles; //按钮标题
@property NSArray *images; //按钮图片
+ (WHC_ButtonGroupParam *)getDefaultParamWithTitleArr:(NSArray*)titleArr; //获取默认参数
@end
@interface WHC_ButtonGroupView : UIView
@property id<WHC_ButtonGroupViewDelegate> delegate;
- (void)changeSelectedStateButtonWithIndex:(NSInteger)index; //改变指定按钮的状态
- (BOOL)deleteButtonWithIndex:(NSInteger)index withTitle:(NSString*)title; //删除指定按钮
- (BOOL)addButtonWithIndex:(NSInteger)index withTitle:(NSString*)title; //添加按钮到指定位子
- (void)switchUIOrientationWithIsHori:(BOOL)isHori withPading:(CGFloat)pad; //转换屏幕处理
- (id)initWithFrame:(CGRect)frame withParam:(WHC_ButtonGroupParam*)param; //初始化
- (void)gotoOtherBtnOptionWithIndex:(NSInteger)index; //切换到其他按钮响应
- (void)modifyButtonTitleForIndex:(NSInteger)index withTitle:(NSString*)title; //修改指定按钮标题
@end
WHC_ButtonGroupView.m源文件如下:
//
// buttonGroupView.m
// bhtrader
//
// Created by apple on 14-6-6.
// Copyright (c) 2014年 InvestGu. All rights reserved.
//
#import "WHC_ButtonGroupView.h"
#define kLineWidth (1.0)
#define KANMATION_TIME 0.2
@implementation WHC_ButtonGroupParam
//返回默认样式
+(WHC_ButtonGroupParam *)getDefaultParamWithTitleArr:(NSArray*)titleArr{
WHC_ButtonGroupParam * groupParam = [WHC_ButtonGroupParam new];
groupParam.normalBackColor = [UIColor grayColor];
groupParam.selectedBackColor = [UIColor blackColor];
groupParam.markColor = [UIColor clearColor];
groupParam.segmentLineY = 0.0;
groupParam.segmentLineColor = [UIColor blackColor];
groupParam.normalTextColor = [UIColor whiteColor];
groupParam.selectedTextColor = [UIColor grayColor];
groupParam.titles = titleArr;
groupParam.images = nil;
groupParam.scroll = NO;
groupParam.headLine = YES;
groupParam.footLine = YES;
groupParam.firstSegmentLine = YES;
groupParam.markViewDown = NO;
groupParam.fontSize = 16.0;
groupParam.markPading = 5.0;
return groupParam;
}
@end
@interface WHC_ButtonGroupView ()<UIScrollViewDelegate>{
NSMutableArray * btns; //存储按钮数组
NSMutableArray * segmentLineLabs; //存储分隔线数组
WHC_ButtonGroupParam * btnParam; //存储创建参数
UIScrollView * sl; //滑动控件
UIView * markView; //游标控件
UILabel * headLine; //头部线
UILabel * footLine; //底部线
NSInteger currBtnIndex; //当前按钮下标
CGRect rect; //备份该控件矩形区域
CGPoint center; //中心点
CGFloat screenWidth; //屏幕宽度
CGFloat screenHeight; //屏幕高度
}
@end
@implementation WHC_ButtonGroupView
//初始化控件
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
screenWidth = [UIScreen mainScreen].bounds.size.width;
screenHeight = [UIScreen mainScreen].bounds.size.height;
rect = frame;
btns = [NSMutableArray array];
segmentLineLabs = [NSMutableArray array];
CGFloat btnHeight = btnParam.btnHeight == 0.0 ? frame.size.height:btnParam.btnHeight;
btnParam.btnHeight = btnHeight;
btnParam.btnWidth = btnParam.btnWidth == 0.0 ? (rect.size.width > screenWidth ? screenWidth : rect.size.width)/(CGFloat)btnParam.titles.count : btnParam.btnWidth;
sl = [[UIScrollView alloc]initWithFrame:CGRectMake(0.0, 0.0,btnParam.scroll == NO ? frame.size.width : btnParam.scrollWidth, btnParam.btnHeight)];
sl.backgroundColor = btnParam.normalBackColor;
sl.delegate = self;
sl.contentSize = CGSizeMake(btnParam.btnWidth * btnParam.titles.count, 0);
sl.scrollEnabled = btnParam.scroll;
sl.showsVerticalScrollIndicator = NO;
sl.showsHorizontalScrollIndicator = NO;
[self layoutUI];
[self addSubview:sl];
if(headLine != nil){
[self bringSubviewToFront:headLine];
}
if(footLine != nil){
[self bringSubviewToFront:footLine];
}
}
return self;
}
//初始化控件
- (id)initWithFrame:(CGRect)frame withParam:(WHC_ButtonGroupParam*)param
{
btnParam = param;
return [self initWithFrame:frame];
}
//布局ui
-(void)layoutUI{
NSInteger count = btnParam.titles.count;
CGFloat btnWidth = btnParam.btnWidth == 0.0 ? (rect.size.width > screenWidth ? screenWidth : rect.size.width)/(CGFloat)count : btnParam.btnWidth;
CGFloat btnHeight = btnParam.btnHeight == 0.0 ? rect.size.height:btnParam.btnHeight;
CGFloat lineWidth = btnParam.headLine || btnParam.footLine ? kLineWidth : 0;
btnParam.btnWidth = btnWidth;
btnParam.btnHeight = btnHeight;
for (NSInteger i = 0; i < count; i++) {
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(i * btnParam.btnWidth, 0.0, (btnParam.btnWidth - kLineWidth) + (i == count -1 ? kLineWidth : 0.0), btnParam.btnHeight);
btn.tag = i;
btn.titleLabel.font = [UIFont boldSystemFontOfSize:btnParam.fontSize];
btn.backgroundColor = btnParam.normalBackColor;
[btn setTitle:btnParam.titles[i] forState:UIControlStateNormal];
if(btnParam.images.count > 0){
[btn setImage:[UIImage imageNamed:btnParam.images[i]] forState:UIControlStateNormal];
NSString * strText = @"冠军";
//兼容低版本
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
CGSize fontSize = [strText sizeWithFont:[UIFont systemFontOfSize:btnParam.fontSize]];
#pragma clang diagnostic pop
CGFloat left = (btnParam.btnWidth - fontSize.width * 2.0)/2.0;
CGFloat top = 5.0;
CGFloat bottom = 5.0;
CGFloat right = left + fontSize.width;
btn.imageEdgeInsets = UIEdgeInsetsMake(top, left, bottom, right);
}
[btn setTitleColor:btnParam.normalTextColor forState:UIControlStateNormal];
[btn setTitleColor:btnParam.selectedTextColor forState:UIControlStateSelected];
[btn addTarget:self action:@selector(clickBtns:) forControlEvents:UIControlEventTouchUpInside];
if(i == btnParam.currIndex){
btn.selected = YES;
if(btnParam.selectedBackColor != nil)
btn.backgroundColor = btnParam.selectedBackColor;
}
[sl addSubview:btn];
[btns addObject:btn];
if(!btnParam.firstSegmentLine && i >= count - 1){
break;
}
UILabel * segmentLine = [[UILabel alloc]initWithFrame:CGRectMake((btnParam.btnWidth - kLineWidth) * (i + 1) + i * kLineWidth, btnParam.segmentLineY, kLineWidth, btnHeight - 2 * btnParam.segmentLineY)];
segmentLine.backgroundColor = btnParam.segmentLineColor;
[segmentLineLabs addObject:segmentLine];
[sl addSubview:segmentLine];
}
if(btnParam.firstSegmentLine){
UILabel * segmentLine = [[UILabel alloc]initWithFrame:CGRectMake(0.0, btnParam.segmentLineY, kLineWidth, btnHeight - 2 * btnParam.segmentLineY)];
segmentLine.backgroundColor = btnParam.segmentLineColor;
[segmentLineLabs addObject:segmentLine];
[sl addSubview:segmentLine];
}
if(btnParam.headLine){
headLine = [[UILabel alloc]initWithFrame:CGRectMake(0.0, 0.0, rect.size.width, lineWidth)];
headLine.backgroundColor = btnParam.segmentLineColor;
[self addSubview:headLine];
}
if(btnParam.footLine){
footLine = [[UILabel alloc]initWithFrame:CGRectMake(0.0, btnParam.btnHeight - lineWidth, rect.size.width, lineWidth)];
footLine.backgroundColor = btnParam.segmentLineColor;
[self addSubview:footLine];
}
CGFloat markWidth = btnParam.btnWidth - 2 * btnParam.markPading;
if (btnParam.markViewDown) {
markView = [[UIView alloc]initWithFrame:CGRectMake(btnParam.markPading, btnParam.btnHeight - 2.5, markWidth, 2.5)];
}else{
markView = [[UIView alloc]initWithFrame:CGRectMake(btnParam.markPading, 1.0, markWidth, 2.5)];
}
markView.backgroundColor = btnParam.markColor;
[sl addSubview:markView];
}
//单击按钮处理
-(void)clickBtns:(UIButton *)btn
{
NSInteger tag = btn.tag;
[self changeSelectedStateButtonWithIndex:tag];
if(_delegate){
if([_delegate respondsToSelector:@selector(whcButtonGroup:index:)]){
[_delegate whcButtonGroup:self index:tag];
}
}
}
//屏幕切换处理
-(void)switchUIOrientationWithIsHori:(BOOL)isHori withPading:(CGFloat)pad
{
if (isHori){
CGRect rc = CGRectZero;
rc = CGRectMake(0.0, 0.0, screenHeight, btnParam.btnHeight);
self.frame = rc;
self.center = CGPointMake(screenWidth - (pad + btnParam.btnHeight / 2.0) + pad + btnParam.btnHeight, screenHeight / 2.0);
center = self.center;
rc = CGRectMake(0.0, 0.0,btnParam.scroll == NO ? screenHeight : btnParam.scrollWidth, btnParam.btnHeight);
sl.frame = rc;
NSInteger btnCount = btns.count;
CGFloat btnWidth = screenHeight / (CGFloat)btnCount;
for (int i = 0; i < btnCount; i++) {
UIButton * tempBtn = btns[i];
rc = CGRectMake(i * btnWidth, 0.0, (btnWidth - kLineWidth) + (i == btnCount -1 ? kLineWidth : 0.0), btnParam.btnHeight);
tempBtn.frame = rc;
}
NSInteger labCount = segmentLineLabs.count;
for (int i = 0; i < labCount; i++) {
UILabel * tempLab = segmentLineLabs[i];
rc = CGRectMake((btnWidth - kLineWidth) * (i + 1) + i * kLineWidth, btnParam.segmentLineY, kLineWidth, btnParam.btnHeight - 2 * btnParam.segmentLineY);
tempLab.frame = rc;
}
UILabel * tempLab = segmentLineLabs.lastObject;
tempLab.frame = CGRectMake(0.0, btnParam.segmentLineY, kLineWidth, btnParam.btnHeight - 2 * btnParam.segmentLineY);
if(headLine != nil){
rc = CGRectMake(0.0, 0.0, screenHeight, kLineWidth);
headLine.frame = rc;
}
if(footLine != nil){
rc = CGRectMake(0.0, btnParam.btnHeight - kLineWidth, screenHeight, kLineWidth);
footLine.frame = rc;
}
CGFloat markWidth = btnParam.btnWidth - 2 * btnParam.markPading;
if(btnParam.markViewDown){
rc = CGRectMake(btnParam.currIndex * btnWidth + (btnWidth - markWidth)/2.0, btnParam.btnHeight - 2.5, markWidth, 2.5);
markView.frame = rc;
}else{
rc = CGRectMake(btnParam.currIndex * btnWidth + (btnWidth - markWidth)/2.0, 1.0, markWidth, 2.5);
markView.frame = rc;
}
self.transform = CGAffineTransformMakeRotation(M_PI_2);
[UIView animateWithDuration:KANMATION_TIME animations:^{
self.center = CGPointMake(center.x - (pad + btnParam.btnHeight), center.y);
}];
}else{
#if 0
self.transform = CGAffineTransformMakeRotation(0);
[UIView animateWithDuration:KANMATION_TIME animations:^{
// self.center = center;
}];
CGRect rc = CGRectZero;
rc = rect;
self.frame = rc;
rc = CGRectMake(0.0, 0.0,btnParam.scroll == NO ? rect.size.width : btnParam.scrollWidth, btnParam.btnHeight);
sl.frame = rc;
NSInteger btnCount = btns.count;
for (int i = 0; i < btnCount; i++) {
UIButton * tempBtn = btns[i];
rc = CGRectMake(i * btnParam.btnWidth, 0.0, (btnParam.btnWidth - kLineWidth) + (i == btnCount -1 ? kLineWidth : 0.0), btnParam.btnHeight);
tempBtn.frame = rc;
}
NSInteger labCount = segmentLineLabs.count;
for (int i = 0; i < labCount; i++) {
UILabel * tempLab = segmentLineLabs[i];
rc = CGRectMake((btnParam.btnWidth - kLineWidth) * (i + 1) + i * kLineWidth, btnParam.segmentLineY, kLineWidth, btnParam.btnHeight - 2 * btnParam.segmentLineY);
tempLab.frame = rc;
}
if(headLine != nil){
rc = CGRectMake(0.0, 0.0, rect.size.width, kLineWidth);
headLine.frame = rc;
}
if(footLine != nil){
rc = CGRectMake(0.0, btnParam.btnHeight - kLineWidth, rect.size.width, kLineWidth);
footLine.frame = rc;
}
if(btnParam.markViewDown){
rc = CGRectMake(btnParam.currIndex * btnParam.btnWidth + (btnParam.btnWidth - btnParam.markWidth)/2.0, btnParam.btnHeight - 2.5, btnParam.markWidth, 2.5);
markView.frame = rc;
}else{
rc = CGRectMake(btnParam.currIndex * btnParam.btnWidth + (btnParam.btnWidth - btnParam.markWidth)/2.0, 1.0, btnParam.markWidth, 2.5);
markView.frame = rc;
}
#endif
self.center = CGPointMake(self.center.x + (pad + btnParam.btnHeight) * 2.0, self.center.y);
}
}
//响应其他按钮
-(void)gotoOtherBtnOptionWithIndex:(NSInteger)index
{
[self clickBtns:btns[index]];
}
//修改按钮标题
-(void)modifyButtonTitleForIndex:(NSInteger)index withTitle:(NSString*)title{
UIButton * btn = btns[index];
[btn setTitle:title forState:UIControlStateNormal];
}
//调整布局
-(void)adjustLayoutWithIndex:(NSInteger)index withTitle:(NSString*)title{
//清空旧存储
for(UIView * view in sl.subviews){
[view removeFromSuperview];
}
NSMutableArray * arr = [NSMutableArray arrayWithArray:btnParam.titles];
[arr removeLastObject];
[arr addObject:((UIButton*)[btns lastObject]).titleLabel.text];
if(title != nil){
[arr insertObject:title atIndex:index];
}else{
[arr removeObjectAtIndex:index];
}
btnParam.titles = nil;
btnParam.titles = [NSArray arrayWithArray:arr];
btnParam.btnWidth = 0.0;
btnParam.btnHeight = 0.0;
btnParam.markPading = 0.0;
[btns removeAllObjects];
[segmentLineLabs removeAllObjects];
markView = nil;
headLine = nil;
footLine = nil;
[self layoutUI];
}
//添加按钮
-(BOOL)addButtonWithIndex:(NSInteger)index withTitle:(NSString*)title{
BOOL result = NO;
if(![btnParam.titles containsObject:title]){
[self adjustLayoutWithIndex:index withTitle:title];
result = YES;
}
return result;
}
//删除按钮
-(BOOL)deleteButtonWithIndex:(NSInteger)index withTitle:(NSString*)title{
BOOL result = NO;
if([btnParam.titles containsObject:title]){
[self adjustLayoutWithIndex:index withTitle:nil];
result = YES;
}
return result;
}
//改变按钮选中状态
-(void)changeSelectedStateButtonWithIndex:(NSInteger)index{
currBtnIndex = index;
for (UIButton * tempBtn in btns) {
tempBtn.selected = NO;
tempBtn.backgroundColor = btnParam.normalBackColor;
}
((UIButton*)btns[index]).selected = YES;
((UIButton*)btns[index]).backgroundColor = btnParam.selectedBackColor;
CGRect markRect = markView.frame;
markRect.origin.x = ((UIButton*)btns[index]).frame.origin.x +
(((UIButton*)btns[index]).frame.size.width - markRect.size.width) / 2.0;
if(index == 0){
index = 1;
}else if (index == btnParam.titles.count - 1){
index = btnParam.titles.count - 2;
}
[UIView animateWithDuration:0.1 animations:^{
markView.frame = markRect;
if(sl.scrollEnabled){
if((index - 1) * btnParam.btnWidth > (sl.contentSize.width - sl.frame.size.width))return ;
[sl setContentOffset:CGPointMake((index - 1) * btnParam.btnWidth, 0) animated:NO];
}
}];
}
@end