大佬教程收集整理的这篇文章主要介绍了iOS 控件封装(又名拧螺丝)之排序按钮的开发,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
前言
排序按钮是实际开发中比较常见的一种控件,最近我也遇到了,今天简单分享下。
OK,先看图:
简单描述一下:
按钮一共有三种状态:非选中、选中升序、选中降序。
按钮的三种状态
点击按钮时有两种情况:
不同状态对应不同的icon,如果没有UI,可以去iconfont 找图标,输入关键词如“上下箭头”就可以找到你需要的icon。
基本思路
继承UIButton,直接在button上放view,设置约束,根据按钮的状态设置对应的图片。
PS:自定义按钮最灵活的做法就是直接在button上放view(在不需要纠结内存和view层级的情况下),简单粗暴、随心所欲。
完整代码
.h文件:
#import <UIKit/UIKit.h> @interface CQSortButton : UIButton /** 按钮文本 */ @property (nonatomic,copy) NSString *title; /** 是否是升序 */ @property (nonatomic,assign,readonly,getter=isAscending) BOOL ascending; @end
.m文件:
#import "CQSortButton.h" @interface CQSortButton () /** 文本label */ @property (nonatomic,strong) UILabel *cq_titleLabel; /** 箭头imageView */ @property (nonatomic,strong) UIImageView *cq_arrowImageView; @end @implementation CQSortButton #pragma mark - 构造方法 - (instanCETypE)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { [self setupUI]; } return self; } #pragma mark - UI搭建 - (void)setupUI { self.layer.borderColor = [UIColor blackColor].CGColor; self.layer.borderWidth = 1; // 文本和图片的父view UIView *contentView = [[UIView alloc] init]; [self addSubview:contentView]; contentView.userInteractionEnabled = NO; [contentView mas_makeConsTraints:^(MASConsTraintMaker *makE) { make.top.bottom.centerX.mas_equalTo(self); make.left.mas_greaterThanOrequalTo(self).mas_offset(3); make.right.mas_lessThanOrequalTo(self).mas_offset(-3); }]; // 文本 self.cq_titleLabel = [[UILabel alloc] init]; [contentView addSubview:self.cq_titleLabel]; self.cq_titleLabel.font = [UIFont boldSystemFontOfSize:13]; self.cq_titleLabel.adjustsFontSizeToFitWidth = YES; [self.cq_titleLabel mas_makeConsTraints:^(MASConsTraintMaker *makE) { make.top.bottom.left.mas_offset(0); }]; // 图片 self.cq_arrowImageView = [[UIImageView alloc] init]; [contentView addSubview:self.cq_arrowImageView]; self.cq_arrowImageView.image = [UIImage imagenamed:@"up_down"]; [self.cq_arrowImageView mas_makeConsTraints:^(MASConsTraintMaker *makE) { make.size.mas_equalTo(CGSizeMake(20,20)); make.centerY.mas_equalTo(contentView); make.left.mas_equalTo(self.cq_titleLabel.mas_right); make.right.mas_equalTo(contentView); }]; } #pragma mark - 赋值选中状态 - (void)setSELEcted:(BOOL)SELEcted { //// 注意: //// SELEcted 表示你要赋值的状态 //// super.SELEcted 表示当前处于的状态 if (SELEcted) { // 即将设置成选中状态 if (super.SELEcted) { // 如果原本就处于选中状态 // 那么就切换筛选状态 _ascending = !_ascending; if (_ascending) { // 升序 self.cq_arrowImageView.image = [UIImage imagenamed:@"red_arrow_up"]; } else { // 降序 self.cq_arrowImageView.image = [UIImage imagenamed:@"red_arrow_down"]; } } else { // 如果之前不是选中状态 // 那么设置成选中的默认排序状态:升序 _ascending = YES; self.cq_arrowImageView.image = [UIImage imagenamed:@"red_arrow_up"]; } } else { // 即将设置成非选中状态 // 设置成非选中状态的图片 self.cq_arrowImageView.image = [UIImage imagenamed:@"up_down"]; } // 最后再赋值 [super setSELEcted:SELEcted]; } #pragma mark - 赋值文本 - (void)settitle:(NSString *)title { _title = title; self.cq_titleLabel.text = title; } @end
使用:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NSArray *titleArray = @[@"同比",@"销售额",@"🙃",@"文字有点多啊"]; NSMutableArray *buttonArray = [NSMutableArray array]; for (int i = 0; i < 4; i++) { CQSortButton *button = [[CQSortButton alloc] init]; [self.view addSubview:button]; button.title = titleArraY[i]; button.tag = CQSortButtonBeginTag + i; [button addTarget:self action:@SELEctor(sortButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; [buttonArray addObject:button]; } // 按钮等宽依次排列 [buttonArray mas_diStributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:0 leadSpacing:0 tailSpacing:0]; [buttonArray mas_makeConsTraints:^(MASConsTraintMaker *makE) { make.top.mas_equalTo(100); make.height.mas_equalTo(40); }]; } - (void)sortButtonClicked:(CQSortButton *)sender { for (int i = 0; i < 4; i++) { CQSortButton *button = [self.View viewWithTag:(CQSortButtonBeginTag + i)]; button.SELEcted = (button.tag == sender.tag); } NSLog(@"第%ld个按钮点击,状态:%@",(long)(sender.tag-CQSortButtonBeginTag),sender.isAscending ? @"升序" : @"降序"); }
知识点及细节
1.如何让两个view整体居中并且不超出父view?
创建父view是关键。
先创建一个父view,这个父view居中于button,左右不设置固定约束,再将两个view放在父view上,左边的view与父view左对齐,右边的view与父view右对齐,左边的view与右边的view水平方向约束确定,撑开父view:
// 文本和图片的父view UIView *contentView = [[UIView alloc] init]; [self addSubview:contentView]; [contentView addSubview:self.cq_titleLabel]; [contentView addSubview:self.cq_arrowImageView]; [self.cq_titleLabel mas_makeConsTraints:^(MASConsTraintMaker *makE) { make.top.bottom.left.mas_offset(0); }]; [self.cq_arrowImageView mas_makeConsTraints:^(MASConsTraintMaker *makE) { make.size.mas_equalTo(CGSizeMake(20,20)); make.centerY.mas_equalTo(contentView); make.left.mas_equalTo(self.cq_titleLabel.mas_right); make.right.mas_equalTo(contentView); }];
不超出父view(此处指button)用mas_greaterThanOrequalTo和mas_lessThanOrequalTo即可:
[contentView mas_makeConsTraints:^(MASConsTraintMaker *makE) { make.top.bottom.centerX.mas_equalTo(self); make.left.mas_greaterThanOrequalTo(self).mas_offset(3); make.right.mas_lessThanOrequalTo(self).mas_offset(-3); }];
2.readonly的使用
/** 是否是升序 */ @property (nonatomic,getter=isAscending) BOOL ascending;
为什么这里要用readonly?
因为这个属性的改变只能是通过内部(自身的.m)改变,而不能通过外部改变,或者说这个属性只是用来反映按钮的一个状态,就像UIScrollView的decelerating属性一样,只是反映scrollView正在减速,不能通过调用scrollView.decelerating = YES让它主动减速。
// returns YES if user isn't dragging (touch up) but scroll view is still moving @property(nonatomic,getter=isDecelerating) BOOL decelerating;
总结一下就是readonly适用于只用来反映对象的状态、特征或特性的属性。
你可以找几个苹果官方文档里的readonly属性好好感受一下。
3.如何使用masonry等宽等间距排列控件?
用masory提供的mas_diStributeViewsAlongAxis方法:
// 按钮等宽依次排列[buttonArray mas_diStributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:0 leadSpacing:0 tailSpacing:0]; [buttonArray mas_makeConsTraints:^(MASConsTraintMaker *makE) { make.top.mas_equalTo(100); make.height.mas_equalTo(40); }];
iOS Masonry 等间隔或等宽高排列多个控件,很实用的技能,建议熟练掌握。
需要注意的是@L_331_21@mas_diStributeViewsAlongAxis这个方法的数组其元素个数必须bigger than one,否则没有效果,masonry源码截取:
- (void)mas_diStributeViewsAlongAxis:(MASAxisTypE)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing { if (self.count < 2) { NSAssert(self.count>1,@"views to diStribute need to bigger than one"); return; } ...... }
所以实际开发中如果你是获取后台的数组来展示的话,务必先判断数组的count。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
以上是大佬教程为你收集整理的iOS 控件封装(又名拧螺丝)之排序按钮的开发全部内容,希望文章能够帮你解决iOS 控件封装(又名拧螺丝)之排序按钮的开发所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。