封装同步的UIActionSheet
发问题
做 iOS 开发的同学想必都用过 UIActionSheet。UIActionSheet 可以弹出一个选择列表,让用户选择列表中的某一项操作。使用 UIActionSheet 非常简单,以下是一个简单的示例代码:
- (void)someButtonClicked { |
但我个人在使用时,感觉 UIActionSheet 有以下 2 个问题:
UIActionSheet 是一个异步的调用,需要设置 delegate 来获得用户选择的结果。这么小粒度的选择界面,把调用显示和回调方法分开写在 2 个方法中,使得原本简单的逻辑复杂了。虽然也不会复杂到哪儿去,但是每次调用 UIActionSheet 就需要另外写一个 delegate 回调方法,让我觉得这是一个过度的设计。如果 UIActionSheet 在弹出界面时,是一个同步调用,在调用完 showInView 方法后,就能获得用户的点击结果,那该多方便。
UIActionSheet 默认的 init 方法比较恶心。cancel Button 其实默认是在最底部的,但是在 init 方法中是放在第一个参数。destructive 默认是列表的第一个。如果你需要的界面不是将 destructive button 放在第一个,就需要再指定一次 destructiveButtonIndex,而这个 index 的下标,是忽略 cancel button 来数的,虽说也不是很麻烦,但是心里感觉比较恶心。
改造 UIActionSheet
基于上面 2 个原因,我想把 UIActionSheet 改造成一个同步的调用。这样,在我调用它的 showInView 方法后,我希望它直接同步地返回用户的选择项,而不是通过一个 Delegate 方法来回调我。另外,我也不希望 init 方法有那么多麻烦的参数,我只希望 init 的时候,指定一个数组能够设置每个 button 的 title 就行了。
于是我写了一个 SynchronizedUIActionSheet 类,这个类将 UIActionSheet 简单封装了一下,利用 CFRunLoopRun 和 CFRunLoopStop 方法来将 UIActionSheet 改造成同步的调用。整个代码如下所示:
SynchronizedUIActionSheet.h 文件:
// SynchronizedUIActionSheet.h |
SynchronizedUIActionSheet.m 文件:
#import "SynchronizedUIActionSheet.h" @implementation SynchronizedUIActionSheet { |
在改造后,调用 ActionSheet 的示例代码如下,是不是感觉逻辑清爽了一些?
- (IBAction)testButtonPressed:(id)sender { |
总结
利用 NSRunLoop 来将原本的异步方法改成同步,可以使我们在某些情形下,方便地将异步方法变成同步方法来执行。
例如以前我们在做有道云笔记 iPad 版的时候,采用的图片多选控件需要用户允许我们获得地理位置信息,如果用户没有选择允许,那个这个图片多选控件就会执行失败。为了不让这个控件挂掉,我们想在用户禁止访问地理位置时,不使用该控件,而使用系统自带的图片单选的 UIImagePickerController 控件来选择图片。对于这个需求,我们明显就希望将获得地理位置信息这个系统确认框做成同步的,使得我们可以根据用户的选择再决定用哪种图片选择方式。最终,我们也用类似上面的方法,用 NSRunLoop 来使我们的异步方法调用暂停在某一行,直到获得用户的反馈后,再往下执行,示例代码如下:
- (id)someCheck { |
封装同步的UIActionSheet的更多相关文章
-
c++封装编写线程池
在csapp学习或者其他linux底层编程的过程中,一般都会举一些多线程或多进程的例子,配合底层同步原语.系统调用api来解释怎么创建多线程/多进程. 但是这些例子和实际项目中所用到的多线程/多进程编 ...
-
Promise的封装
要封装Promise,首先要了解Promise的使用. Promise有以下几个特点:1.Promise是一个构造函数 2.实例化Promise时有两个回调函数,resolve,reject ,成功执 ...
-
iOS面试必看
转载:http://www.jianshu.com/p/5d2163640e26 序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了.今年,找过工作人可能会更深刻地体会到今年的就业形 ...
-
Java基础高级二(多线程)
1.进程和线程的区别:线程是轻量级的,本省不会持太多资源,需要的时候向进程申请 2.线程的状态:创建,可执行,执行中,等待,休眠,阻塞 3.线程状态之间的转换 4.线程API:Thread类,Runn ...
-
Javascript 中的神器——Promise
Promise in js 回调函数真正的问题在于他剥夺了我们使用 return 和 throw 这些关键字的能力.而 Promise 很好地解决了这一切. 2015 年 6 月,ECMAScript ...
-
We have a problem with promises
原文地址:http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/ 用Javascript的小伙伴们,是时候承认了,关于 p ...
-
李洪强iOS经典面试题129
1. 怎么解决缓存池满的问题(cell) ios中不存在缓存池满的情况,因为通常我们ios中开发,对象都是在需要的时候才会创建,有种常用的说话叫做懒加载,还有在UITableView中一般只会创建刚开 ...
-
iOS 知识点梳理
OC的理解与特性 OC作为一门面向对象的语言,自然具有面向对象的语言特性:封装.继承.多态.它既具有静态语言的特性(如C++),又有动态语言的效率(动态绑定.动态加载等).总体来讲,OC确实是一门不错 ...
-
iOS面试必看,最全梳理
序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了.今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,加之,培训机构一火车地向用人单位输送iOS开发人员,打破了生态圈的动态 ...
随机推荐
-
转载:shell脚本之sed使用----替换、变量、转义字符
sed替换的基本语法为:----s后面跟的是分隔符,原字符串可使用.*这种正则表达式进行整行替换 代码如下: sed 's/原字符串/替换字符串/' 单引号里面,s表示替换,三根斜线中间是替换的样式, ...
-
java 内存模型
翻译自wiki百科:https://en.wikipedia.org/wiki/Java_memory_model 没找到直接在wiki上编辑中文的页面,我就在这翻译下,自己学习用. java内存模型 ...
-
1005. 继续(3n+1)猜想 (25)
卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数.例如对n=3进行验证的时候, ...
-
通过HttpClient来调用Web Api接口,实体参数的传递
下面定义一个复杂类型对象 public class User_Info { public int Id { get; set; } public string Name { get; set; } p ...
-
Verdi 看波形常用快捷操作
Verdi看波形的基本操作小结: 快捷键:(大写字母=Shift+小写) g get, signlas添加信号,显示波形n next, Search Forward选定信号按指定的值(上升 ...
-
【学习总结】C-翁恺老师-入门-第4周<;循环控制>;
[学习总结]C-翁恺老师-入门-总 1-阶乘:引入for循环 2-控制循环次数:初始化与控制条件的设置 任何一个for循环都可以写成一个while循环 for中的每一个表达式都是可以省略的:for(; ...
-
Confluence 6 从其他备份中恢复数据
一般来说,Confluence 数据库可以从 Administration Console 或者 Confluence Setup Wizard 中进行恢复. 如果你在恢复压缩的 XML 备份的时候遇 ...
-
Ubuntu 16.04出现:Problem executing scripts APT::Update::Post-Invoke-Success &#39;if /usr/bin/test -w /var/cache/app-info -a -e /usr/bin/appstreamcli; then appstreamcli refresh >; /dev/null; fi&#39;
错误: Reading package lists... Done E: Problem executing scripts APT::Update::Post-Invoke-Success 'if ...
-
用户人品预测大赛--getmax队--竞赛分享
用户人品预测大赛--getmax队--竞赛分享 DataCastle运营 发表于 2016-3-24 14:49:32 533 0 0 答辩PPT
-
(原)用WebBrowser浏览Office Web Apps Server,除去“下载”按钮
对,没错,如果你按关键字找到这篇随笔了,相信一定知道背景,以及我所说的是什么. 上一段子代码. private void timerHideButton_Tick(object sender, Eve ...