iOS自定义控件(简易下拉控件)
文章图片
宝儿姐镇楼 最近自由时间有点多,就开始撸控件。这个是我们常用的一个下拉分类控件,看了很多别人写的,都是用TableView或者CollectionView整合在一起的感觉自定义性没有那么强,所以就尝试用把TableView和CollectionView替换成UIViewController。其他废话不多说了。
1、 接口文件
#import UIKIT_EXTERN NSString *lzDropViewNotification;
NS_ASSUME_NONNULL_BEGIN@class LZDropView;
@protocol LZDropViewDataSource @required/** Height corresponding to controller display */
- (NSArray *)setupCategoryControllerHeightInDropView:(LZDropView *)dropView;
/** Title corresponding controller array */
- (NSArray *)setupCategoryControllerInDropView:(LZDropView *)dropView;
/** Default display of Title Array */
- (NSArray *)setupCategoryTitleNameInDropView:(LZDropView *)dropView;
@end@protocol LZDropViewDelegate /** Click the column and select the information. */
- (void)dropView:(LZDropView *)dropView didSelectAtColumn:(NSInteger)column info:(NSString *)info;
@end@interface LZDropView : UIView
/** Simple page configuration */
@property (nonatomic, weak) id dataSorce;
/** Click proxy event<##> */
@property (nonatomic, weak) id delegate;
@endNS_ASSUME_NONNULL_END
2、 实现文件
#import "LZDropView.h"NSString *lzDropViewNotification = @"nitification";
@interface LZDropView ()@property (nonatomic, strong) NSArray *controllerArray;
@property (nonatomic, strong) NSArray *titleArray;
@property (nonatomic, strong) UIButton *containerView;
@property (nonatomic, strong) NSArray *controllerHeightArray;
@property (nonatomic, strong) NSMutableArray *buttonArray;
@end@implementation LZDropView#pragma mark - Release memory- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}#pragma mark - Initialization- (instancetype)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction:) name:lzDropViewNotification object:nil];
}
return self;
}#pragma mark - Draw the page- (void)setupTitleButton:(NSArray *)array {
CGFloat width = UIScreen.mainScreen.bounds.size.width / array.count;
self.buttonArray = [NSMutableArray array];
for (NSString *name in array) {
NSInteger index = [array indexOfObject:name];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.titleLabel.font = [UIFont systemFontOfSize:15];
[button setTitle:[NSString stringWithFormat:@"%@ ▼", name] forState:UIControlStateNormal];
[button setTitle:[NSString stringWithFormat:@"%@ ▲", name] forState:UIControlStateSelected];
[button setTitleColor:UIColor.grayColor forState:UIControlStateNormal];
[button setTitleColor:UIColor.orangeColor forState:UIControlStateSelected];
button.frame = CGRectMake(width * index, 0, width, 45);
button.tag = index + 1000;
[button addTarget:self action:@selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
[self.buttonArray addObject:button];
}
}#pragma mark - Button click event- (void)buttonTouched:(UIButton *)sender {
if (sender.selected) {
[self closeControllerView];
} else {
[self openControllerViewWithButton:sender];
}
}- (void)backButtonTouched:(UIButton *)sender {
[self closeControllerView];
}#pragma mark - Notification event- (void)notificationAction:(NSNotification *)notification {
if (![self.controllerArray containsObject:notification.object]) {
return;
}NSInteger index = [self.controllerArray indexOfObject:notification.object];
UIButton *button = self.buttonArray[index];
[button setTitle:[NSString stringWithFormat:@"%@ ▼", notification.userInfo.allValues.firstObject] forState:UIControlStateNormal];
if (self.delegate && [self.delegate respondsToSelector:@selector(dropView:didSelectAtColumn:info:)]) {
[self.delegate dropView:self didSelectAtColumn:index info:notification.userInfo.allValues.firstObject];
}[self closeControllerView];
}#pragma mark - Close all controllers.- (void)closeControllerView {[UIView animateWithDuration:0.8 animations:^{
self.containerView.alpha = 0;
self.containerView.frame = CGRectMake(0, CGRectGetMaxY(self.frame), UIScreen.mainScreen.bounds.size.width, 0);
} completion:^(BOOL finished) {
[self.containerView removeFromSuperview];
}];
for (UIButton *button in self.buttonArray) {
button.selected = false;
}
}#pragma mark - Open the corresponding controller.- (void)openControllerViewWithButton:(UIButton *)sender {
for (UIButton *button in self.buttonArray) {
button.selected = false;
}self.containerView.alpha = 1;
for (UIView *view in self.containerView.subviews) {
[view removeFromSuperview];
}UIViewController *vc = self.controllerArray[sender.tag - 1000];
double vcHeight = [self.controllerHeightArray[sender.tag - 1000] doubleValue];
self.containerView.frame = CGRectMake(0, CGRectGetMaxY(self.frame), self.frame.size.width, 0);
vc.view.frame = CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, 0);
[self.superview addSubview:self.containerView];
[self.containerView addSubview:vc.view];
[UIView animateWithDuration:0.6 animations:^{
self.containerView.frame = CGRectMake(0, CGRectGetMaxY(self.frame), self.frame.size.width, UIScreen.mainScreen.bounds.size.height);
vc.view.frame = CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, vcHeight);
} completion:^(BOOL finished) {}];
sender.selected = true;
}#pragma mark - Getter- (UIView *)containerView {
if (!_containerView) {
_containerView = [[UIButton alloc] init];
_containerView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.1];
[_containerView addTarget:self action:@selector(backButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
}
return _containerView;
}#pragma mark - Setter- (void)setDataSorce:(id)dataSorce {
_dataSorce = dataSorce;
if (self.dataSorce && [self.dataSorce respondsToSelector:@selector(setupCategoryControllerInDropView:)]){
self.controllerArray = [self.dataSorce setupCategoryControllerInDropView:self];
}if (self.dataSorce && [self.dataSorce respondsToSelector:@selector(setupCategoryTitleNameInDropView:)]){
self.titleArray = [self.dataSorce setupCategoryTitleNameInDropView:self];
[self setupTitleButton:self.titleArray];
}if (self.dataSorce && [self.dataSorce respondsToSelector:@selector(setupCategoryControllerHeightInDropView:)]) {
self.controllerHeightArray = [self.dataSorce setupCategoryControllerHeightInDropView:self];
}if (self.controllerArray.count != self.titleArray.count ||
self.controllerArray.count != self.controllerHeightArray.count) {
@throw [NSException exceptionWithName:NSStringFromClass([self class]) reason:@"The number of corresponding arrays is inconsistent." userInfo:nil];
}
}@end
使用方式 1.遵循协议
2.初始化
LZDropView *view= [[LZDropView alloc] init];
view.dataSorce= self;
view.delegate= self;
view.backgroundColor = UIColor.whiteColor;
view.frame= CGRectMake(0, 100, UIScreen.mainScreen.bounds.size.width, 45);
[self.view addSubview:view];
- 实现代理和数据源
#pragma mark - LZDropViewDataSource- (NSArray *)setupCategoryControllerInDropView:(LZDropView *)dropView {
return @[[[TableViewController alloc] init],
[[TableViewController alloc] init],
[[TableViewController alloc] init],
[[TableViewController alloc] init]];
}- (NSArray *)setupCategoryTitleNameInDropView:(LZDropView *)dropView {
return @[@"全部",
@"附近",
@"只能排序",
@"筛选"];
}- (NSArray *)setupCategoryControllerHeightInDropView:(LZDropView *)dropView {
return @[[NSNumber numberWithFloat:300],
[NSNumber numberWithFloat:400],
[NSNumber numberWithFloat:410],
[NSNumber numberWithFloat:420]];
}#pragma mark - LZDropViewDelegate- (void)dropView:(LZDropView *)dropView didSelectAtColumn:(NSInteger)column info:(NSString *)info {
NSLog(@"%ld---%@", column, info);
}
- 点击controller中的数据显示在按钮的标题中,这因为跨界面显示,我暂时没有想到好的办法,所以使用强大的通知传值。
- 记录选中状态,应该是控制器里面的操作,这里就没有实现
[[NSNotificationCenter defaultCenter] postNotificationName:lzDropViewNotification object:self userInfo:@{@"key":[NSString stringWithFormat:@"第%ldcell", indexPath.row]}];
文章图片
效果图 【iOS自定义控件(简易下拉控件)】如果有什么不好如果建议的地方,请批评指正!
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- SpringBoot调用公共模块的自定义注解失效的解决
- python自定义封装带颜色的logging模块
- iOS中的Block
- 列出所有自定义的function和view
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 2019-08-29|2019-08-29 iOS13适配那点事
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- iOS面试题--基础
- 接口|axios接口报错-参数类型错误解决