原文链接:http://www.jianshu.com/p/cfb87a7db7b1
本文为 iOS 自定义视图封装《一劳永逸》系列的第四期,旨在提供封装思路,结果固然重要,但理解过程才最好。授人以鱼不如授人以渔。 —— 由卖报的小画家Sure分享
前言

本文为iOS自定义视图封装《一劳永逸》系列的第四期,旨在提供封装思路,结果固然重要,但理解过程才最好。授人以鱼不如授人以渔。⚠️文章旨在帮助封装程度较低的朋友们,大神可无视勿喷。

历史文章链接列表:
  • 一劳永逸,iOS引导蒙版封装流程
  • 一劳永逸,iOS网页视图控制器封装流程
  • 一劳永逸,iOS多选弹窗封装流程
正文

最近更新项目需求,需要重构导航选取模块,故将封装流程进行分享,效果图如下:

导航选取弹窗

根据效果图情况,可知标题栏位置需自定义,且选项位置等文字样式可调节,因此无法利用系统的UIActionSheet或UIAlertController进行实现,需自定义视图,并考虑到适用场景,该ActionSheet后续会用于其他功能模块中,所以要封装成通用类。

继续分析需求,用什么控件作为主体会更好呢?没错,UITableView是在适合不过了,见刨析图:

刨析图

如上设计的优势在于可将自定义View传入做为TableView的表头视图tableHeaderView。对于选项位置若需定制其它样式可自定义Cell进行设置。因此可满足自定义ActionSheet的多种场景。

根据刨析图,首先我们分别创建maskView与主体TableView。这里需注意的是为了实现效果我们需要将TableView的颜色置为透明。

_tableView.backgroundColor = [UIColor clearColor];

并且我们要将TableView分为两组,即主体选项与取消按钮分离,因此设置代理方法:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return 2;
}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return (section == 0)?_optionsArr.count:1;
}

接下来进行处理视图的圆角效果。TableView主体做圆角效果这个不用多说,需要注意的是如何处理好TableViewCell的圆角形式,若仍然简单设置layer.cornerRadius会出现如下情况:

效果图

显然很难看,设计看到估计会崩溃,因此我们需要做的处理为仅为选项中的最后一项做圆角处理,即图中的高德地图选项,并且为了美观效果,要达到只为其左下角与右下角做处理。

这里我们需要借助UIBezierPath与CAShapeLayer进行实现。判断是否为最后选项,然后进行如下设置。

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:cell.contentView.bounds byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 10)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
maskLayer.frame = cell.contentView.bounds;
maskLayer.path = maskPath.CGPath;
cell.layer.mask = maskLayer;

其中byRoundingCorners即为设置所需处理边角参数。有如下枚举克进行选择:

typedef NS_OPTIONS(NSUInteger, UIRectCorner) {UIRectCornerTopLeft     = 1 << 0,UIRectCornerTopRight    = 1 << 1,UIRectCornerBottomLeft  = 1 << 2,UIRectCornerBottomRight = 1 << 3,UIRectCornerAllCorners  = ~0UL
};

比如将byRoundingCorners设置为UIRectCornerTopLeft| UIRectCornerBottomRight,即左上与右下设置,View的效果为:

效果图

经过上述调整,视图的圆角效果完成,最后设置组尾透明视图即可:

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {return SPACE;
}- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, SPACE)];footerView.backgroundColor = [UIColor clearColor];return footerView;
}

做好如上处理后基本的UI效果即已完成。

接下来我们考虑外漏方法问题,简单模拟UIActionSheet的创建形式,公开方法:

- (instancetype)initWithTitleView:(UIView*)titleViewoptionsArr:(NSArray*)optionsArrcancelTitle:(NSString*)cancelTitleselectedBlock:(void(^)(NSInteger))selectedBlockcancelBlock:(void(^)())cancelBlock;

调用如下:

SureCustomActionSheet *optionsView = [[SureCustomActionSheet alloc]initWithTitleView:self.headView optionsArr:self.dataArr cancelTitle:@"取消" selectedBlock:^(NSInteger index) {} cancelBlock:^{}];
[self.view addSubview:optionsView];

这样即可将所需头视图、取消文字传入,并处理选项事件等。

最后简单给予视图显示与隐藏的效果,并在欠当的时机调用即可,且这里我们需要调节TableView的高度,使其适应所包含内容高度。

- (void)show {_tableView.frame = CGRectMake(SPACE, Screen_height, Screen_Width - (SPACE * 2), _tableView.rowHeight * (_optionsArr.count + 1) + _headView.bounds.size.height + (SPACE * 2));[UIView animateWithDuration:.5 animations:^{CGRect rect = _tableView.frame;rect.origin.y -= _tableView.bounds.size.height;
        _tableView.frame = rect;}];
}- (void)dismiss {[UIView animateWithDuration:.5 animations:^{CGRect rect = _tableView.frame;rect.origin.y += _tableView.bounds.size.height;
        _tableView.frame = rect;} completion:^(BOOL finished) {[self removeFromSuperview];}];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {[self dismiss];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {[self dismiss];
}

至此,该需求效果已基本完成,如上摘取部分代码,demo已上传github,需要可自行下载。
一劳永逸,iOS自定义ActionSheet封装流程demo

一劳永逸,iOS 自定义 ActionSheet 封装流程相关推荐

  1. ip打包相对路径 vivado_Vivado自定义IP封装流程

    一,概述 将已有的FPGA功能模块封装成IP,方便在Vivado中使用. 二,IP封装流程 在Vivado工程中,选择菜单栏中的Tools,然后再下拉菜单中选择Creat and Package IP ...

  2. iOS 自定义转场动画浅谈

    代码地址如下: http://www.demodashi.com/demo/11612.html 路漫漫其修远兮,吾将上下而求索 前记 想研究自定义转场动画很久了,时间就像海绵,挤一挤还是有的,花了差 ...

  3. WebClip完成IOS的Wap封装

    title: WebClip完成IOS的Wap封装 tags: WebClip,IOS author: Clown95 背景 当我们使用PC频繁访问某一个网站的时候,大部分人的做法是创建一个书签或者直 ...

  4. ios客户端学习笔记(六):iOS客户端的工作流程

    iOS客户端的工作流程可以简单地概括为: 用户操作 -> 视图显示 -> 交互处理 -> 数据获取 -> 数据处理 -> 数据展示. 结合代码对每个工作流程进行更为具体. ...

  5. Unity3D 游戏引擎之IOS自定义游戏摇杆与飞机平滑的移动(十一)

    Unity3D 游戏引擎之IOS自定义游戏摇杆与飞机平滑的移动 雨松MOMO原创文章如转载,请注明:转载至我的独立域名博客雨松MOMO程序研究院,原文地址:http://www.xuanyusong. ...

  6. iOS最新打包发布流程

    关于如何发布iOS应用到App Stroe,苹果开发者中心已经给出了很详细的说明.和普通的iOS应用一样,使用React Native开发的iOS应用也需要使用普通的iOS应用的发布流程,总的来说,主 ...

  7. iOS 自定义 UICollectionView汇总

    文章目录 引言 I .iOS上传图片视图的封装[支持删除和添加] 1.1 demo源码下载: 1.2 计算cell的高度 II.风险商户材料证明视图 2.1 cellV的高度计算 2.2 自定义col ...

  8. 2022最新iOS最新打包发布流程

    关于如何发布iOS应用到App Stroe,苹果开发者中心已经给出了很详细的说明.和普通的iOS应用一样,使用React Native开发的iOS应用也需要使用普通的iOS应用的发布流程,总的来说,主 ...

  9. iOS自定义View 控件自动计算size能力

    iOS自定义View 控件自动计算size能力 背景 在使用 UILabel 和 UIImage 的时候,不用指定宽高约束,控件也不会报约束缺失,还可以根据内容自己确定适合的宽高,特别适合 Xib 和 ...

最新文章

  1. ubuntu下载安装MaskRCNN-benchmark
  2. nRF52832 — 连接指定name、UUID、addr的蓝牙设备
  3. 为什么美团打车、滴滴外卖必败?君智谢伟山揭秘了背后的竞争战略逻辑
  4. 闪回的用途与实战(闪回表,闪回删除,闪回重名删除,闪回版本查询)
  5. use SAP web IDE to commit change to git
  6. [JavaWeb-HTML]HTML概念介绍和快速入门
  7. linux 同步IO: sync msync、fsync、fdatasync与 fflush
  8. 目前最全的《Android面试题及解析》!面试真题解析
  9. 标识为普通SQL语法
  10. 计算机音乐 phd,美国大学音乐(Music)专业PhD排名
  11. 不显示表头_技术干货 | 基于数模混合型SoC实现的两线制高精度无源表头方案
  12. ActiveX: 如何用.inf和.ocx文件生成cab文件
  13. c语言交换两个数字 位运算_交换两个8位数字| 8086微处理器
  14. dpkg: error processing package oracle-java8-installer (--configure):
  15. 取消endnotes参考文献格式域的步骤_大学体悟-毕业论文格式篇
  16. sicily 1022. Train Problem
  17. SSH与FTP之间的关系与区别
  18. 金蝶KIS15.1专业版注册流程和企业认证流程
  19. 计算机主板USB接口介绍,如何解决计算机主板USB接口供电不足
  20. TF卡,Micro SD卡,Micro SDHC卡

热门文章

  1. crud springmvc
  2. 浅谈《think in java》:一 对象导论总结
  3. 【转载】图像缩放与插值理论基础
  4. linux下安装hadoop
  5. 日期NSDate的使用
  6. DataTable的Compute功能详解
  7. SQLServer中设置XML索引
  8. 又偷懒了4个月,督促自己
  9. COMVariantType的Date类型
  10. 【C++】容器与继承