iOS自定义控件:简易下拉控件

最近自由时间有点多,就开始撸控件。这个是我们常用的一个下拉分类控件,看了很多别人写的,都是用TableView或者CollectionView整合在一起的感觉自定义性没有那么强,所以就尝试用把TableView和CollectionView替换成UIViewController。其他废话不多说了。

1、 接口文件
#import <UIKit/UIKit.h>

UIKIT_EXTERN NSString *lzDropViewNotification;

NS_ASSUME_NONNULL_BEGIN

@class LZDropView;
@protocol LZDropViewDataSource <NSObject>

@required

/** Height corresponding to controller display */
- (NSArray<NSNumber *> *)setupCategoryControllerHeightInDropView:(LZDropView *)dropView;
/** Title corresponding controller array */
- (NSArray<UIViewController *> *)setupCategoryControllerInDropView:(LZDropView *)dropView;
/** Default display of Title Array */
- (NSArray<NSString *> *)setupCategoryTitleNameInDropView:(LZDropView *)dropView;

@end

@protocol LZDropViewDelegate <NSObject>

/** 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 <LZDropViewDataSource> dataSorce;
/** Click proxy event<##> */
@property (nonatomic, weak) id <LZDropViewDelegate> delegate;

@end

NS_ASSUME_NONNULL_END
复制代码
2、 实现文件
#import "LZDropView.h"

NSString *lzDropViewNotification = @"nitification";

@interface LZDropView ()

@property (nonatomic, strong) NSArray<UIViewController *> *controllerArray;
@property (nonatomic, strong) NSArray<NSString *> *titleArray;
@property (nonatomic, strong) UIButton *containerView;
@property (nonatomic, strong) NSArray<NSNumber *> *controllerHeightArray;
@property (nonatomic, strong) NSMutableArray<UIButton *> *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<NSString *> *)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<LZDropViewDataSource>)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.遵循协议

<LZDropViewDataSource, LZDropViewDelegate>
复制代码

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<UIViewController *> *)setupCategoryControllerInDropView:(LZDropView *)dropView {
    return @[[[TableViewController alloc] init],
             [[TableViewController alloc] init],
             [[TableViewController alloc] init],
             [[TableViewController alloc] init]];
}

- (NSArray<NSString *> *)setupCategoryTitleNameInDropView:(LZDropView *)dropView {
    return @[@"全部",
             @"附近",
             @"只能排序",
             @"筛选"];
}

- (NSArray<NSNumber *> *)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]}];
复制代码

如果有什么不好如果建议的地方,请批评指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值