• iOS 可高度自定义的底部弹框


    技术: iOS Objective-C
     

    概述

    一个可以让开发者通过编写 tableView 的内容随心所欲的定制自己想要的底部弹框

    详细

    一. 运行效果图

    image.png

    二. 实现过程

    1. 实现一个有遮罩效果的半透明 view,然后添加一个可设置展示内容高度的 contentView

    // 这个遮罩是可以遮住全屏
    - (void)createUI{
        self.frame = CGRectMake(0, 0, SS_ScreenW, SS_ScreenH);
        self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]; 
        self.userInteractionEnabled = YES;
        [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(disMissView)]];
        [self.contentView addSubview:self.tbView]; 
    }
    // contentView 是通过懒加载实现的
    - (UIView *)contentView{
        if (!_contentView) {
            _contentView = [UIView new];
            _contentView.backgroundColor = [UIColor whiteColor]; 
            _contentView.frame = CGRectMake(0, SS_ScreenH - _contentHeight - SS_BottomMargin,  SS_ScreenW, _contentHeight + SS_BottomMargin);
            _contentView.opaque = YES;
            [self addSubview:_contentView];
        }
        return _contentView;
    }

    2. 我们实现的底部弹框实质上一个可滑动的表单(tableView),在 contentView 上添加一个 tableView

    - (UITableView *)tbView{
        if (!_tbView) {
    //        _tbView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
            _tbView = [UITableView new];
            _tbView.delegate = self;
            _tbView.dataSource = self;
            [_tbView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"ss"];
        }
        return _tbView;
    }

    3. 通过设置UIView 动画,实现遮罩 menuView 的展示和消失效果

    // 将 menuView 展示在父 view 上
    [view addSubview:self];
        [view addSubview:self.contentView];
        self.contentView.frame = CGRectMake(0, SS_ScreenH, SS_ScreenW, _contentHeight);
        __weak typeof(self) weakSelf = self;
        [UIView animateWithDuration:_animationDuration animations:^{
            self.alpha = 1.0;
            self.contentView.frame = CGRectMake(0, SS_ScreenH - weakSelf.contentHeight - SS_BottomMargin, SS_ScreenW, weakSelf.contentHeight + SS_BottomMargin);
        } completion:^(BOOL finished) {
            
        }];
        
    // 将 menuView 从父 view 上移除
    __weak typeof(self) weakSelf = self;
        [UIView animateWithDuration:_animationDuration animations:^{
            self.alpha = 0.0;
            self.contentView.frame = CGRectMake(0, SS_ScreenH, SS_ScreenW, weakSelf.contentHeight);
        } completion:^(BOOL finished) {
            [self removeFromSuperview];
            [self.contentView removeFromSuperview];
        }];

    4. 实现选项和头部的定制化

    通过编写自己的代理方法,让开发人员根据自己项目的实际需要设置各个选项,并且可以定制固定的头部以及底部

     

    @protocol SSMenuViewDelegate <NSObject>
    @required;
    // 返回 tableView 的行数
    - (NSInteger)menuTableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
    // 返回 tableViewCell 需要自定义 cell 的分割线
    - (UITableViewCell *)menuTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    @optional;
    // 设置组数
    - (NSInteger)menuNumberOfSectionsInTableView:(UITableView *)tableView;
    // 选中某个 tableView Cell
    - (void)menuTableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
    // 定义每个选项的cell的高度
    - (CGFloat)menuTableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
    // 定义headerView
    - (UIView *)menuTableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
    // 定义headerView 的高度
    - (CGFloat)menuTableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
    // 定义 footterView
    - (UIView *)menuTableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
    - (CGFloat)menuTableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
    @end

     

    三. 项目结构

    image.png

    四. 使用手册

    1. 首先,根据目录,将 SSMenuView.h, SSMenuView.m 文件,添加到自己项目中

    2. 创建弹框控件

    由于在使用类似弹框的时候,用户可能会多次点击使用,为了避免重复创建,建议使用懒加载创建一个弹窗控件

    # pragma
    # pragma mark - Lazy -
    - (SSMenuView *)menuView{
        if (!_menuView) {
            _menuView = [SSMenuView new];
            _menuView.delegate = self;
    //        _menuView.contentHeight = 44 * 6;
    //        _menuView.tbView.separatorStyle = UITableViewCellSeparatorStyleNone;
        }
        return _menuView;
    }

    3. 根据自己的项目需要,创建自己的弹框内容

    # pragma
    # pragma mark - SSMenuViewDelegate -
    - (NSInteger)menuTableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return 4;
    }
    - (UITableViewCell *)menuTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
        if (!cell) {
            cell = [[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:@"cellID"];
        }
        cell.textLabel.textAlignment = NSTextAlignmentCenter;
        cell.textLabel.text = [NSString stringWithFormat:@"这是选项%ld",indexPath.row];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        return cell;
    }
    - (CGFloat)menuTableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
        return 44;
    }
    - (CGFloat)menuTableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
        return 44;
    }
    - (UIView *)menuTableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
        UIView *footer = [UIView new];
        footer.backgroundColor = [UIColor orangeColor];
        return footer;
    }
    - (UIView *)menuTableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
        UIView *header = [UIView new];
        header.backgroundColor = [UIColor whiteColor];
        header.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44);
        UILabel *lab = [UILabel new];
        lab.text = @"这是选项的头部";
        [header addSubview:lab];
        lab.textAlignment = NSTextAlignmentCenter;
        lab.frame = header.frame;
        
        return header;
    }

    4. 根据需要,在触发点击事件,弹出弹框

    此处,有2种展示方式,根据开发者自己的需要选择是否将弹框完全全屏

     

    - (IBAction)click:(id)sender {
    //    [self.menuView showInView:self.view];
        [self.menuView showInWindow];
    }
    //  隐藏弹框
    [self.menuView disMissView];

     

    注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

  • 相关阅读:
    四则运算02
    第三周学习进度条
    《构建之法》阅读笔记1
    第二周学习进度条
    四则运算01
    第八周进度条
    每日站立会日07,08
    每日站立会议06
    每日站立会议05
    每日站立会议04
  • 原文地址:https://www.cnblogs.com/demodashi/p/10503414.html
Copyright © 2020-2023  润新知