iOS自定义控件(简易下拉控件)

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

  1. 实现代理和数据源
#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); }

  1. 点击controller中的数据显示在按钮的标题中,这因为跨界面显示,我暂时没有想到好的办法,所以使用强大的通知传值。
  2. 记录选中状态,应该是控制器里面的操作,这里就没有实现
[[NSNotificationCenter defaultCenter] postNotificationName:lzDropViewNotification object:self userInfo:@{@"key":[NSString stringWithFormat:@"第%ldcell", indexPath.row]}];

iOS自定义控件(简易下拉控件)
文章图片
效果图 【iOS自定义控件(简易下拉控件)】如果有什么不好如果建议的地方,请批评指正!

    推荐阅读