iOS:简单使用UIAlertVIew和UIActionSheet
做iOS开发的同学想必都用过UIAlertVIew或者UIActionSheet。UIAlertVIew 可以弹出一个出现在屏幕中间的提示视图,给用户展示信息,并让用户自己选择操作,UIActionSheet可以弹出一个选择列表,让用户选择列表中的某一项操作。使用UIAlertVIew和UIActionSheet非常简单,以下是一个简单的示例代码:
//UIAlertView
- (void)someButtonClicked {//初始化AlertView
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"AlertViewTest"
message:@"message"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OtherBtn",nil];
[alert show];
}
//按钮点击事件的代理
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(@"clickButtonAtIndex:%d",(int)buttonIndex);
//index为-1则是取消,
}
//UIActionSheet
- (void)someButtonClicked {
UIActionSheet * sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"ddd" destructiveButtonTitle:@"aaa" otherButtonTitles:@"bbb", @"ccc", @"ddd", nil];
sheet.destructiveButtonIndex = 1;
[sheet showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(@"result = %d", (int)buttonIndex);
}
虽然使用已经算是比较简单了,但我觉得还是比较麻烦他们都需要设置delegate来获得用户选择的结果。这么小的界面,把调用显示和回调方法分开写在2个方法中,使得原本简单的逻辑复杂了。虽然也不会复杂到哪儿去,但是每次调用他们就需要另外写一个delegate回调方法,觉得还是比较麻烦。
于是便产生了,分别给它们写一个category 用来对原生的ui再做一层简单地封装。(一些复杂的暂不考虑)然后用block来做回调,这样子,一块简单地东西就不用分开在两个地方了(才不要拆散它们)。
我们先简单地分析
UIAlertVIew 和
UIActionSheet,其实他们需要的东西,并不多,只是按钮的事件和对应的action,UIAlertVIew还多了一个Title和message,但这些在初始化里面就已经初始化好了。造成他们分离的主要原因还是action和init分离了。所以要完成这个不让他们分离的目的,实现这个category
首先我们需要一个 button的模型来封装 button的title 和 对应的事件,事件用block来代替代理(这样就可以让他们在一起了)。
于是我顺手在github上搜索了一下,发现了这个
https://github.com/jivadevoe/UIAlertView-Blocks
哈哈哈哈,全文终~~
好吧,不闹,既然那让我们来看一下它的实现,这个扩展很简单,就是六个文件,对应RIButtonItem.h、RIButtonItem.m
UIActionSheet+Blocks.h、UIActionSheet+Blocks.m
UIAlertView+Blocks.h、UIAlertView+Blocks.m
RIButtonItem.h
@interface RIButtonItem : NSObject
{
NSString *label;
void (^action)();
}
@property (strong, nonatomic) NSString *label;
@property (copy, nonatomic) void (^action)();
+(id)item;
+(id)itemWithLabel:(NSString *)inLabel;
@end
ok,我们很容易看到,这里面的内容和我们前面想的实现几乎一样,用一个label来存储标题,(^action)()来记录点击按钮的事件。
RIButtonItem.m代码很简单,这里不贴了。
剩下的两个UIAlertView+Blocks UIActionSheet+Blocks 因为实现类似我们来看一个的实现
UIAlertView+Blocks.h
#import <UIKit/UIKit.h>
#import "RIButtonItem.h"`
@interface UIAlertView (Blocks) <UIActionSheetDelegate>
-(id)initWithTitle:(NSString *)inTitle message:(NSString *)inMessage cancelButtonItem:(RIButtonItem *)inCancelButtonItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... NS_REQUIRES_NIL_TERMINATION; //1
- (NSInteger)addButtonItem:(RIButtonItem *)item; //2
@end
1.我们可以看到初始化方法几乎和UIAlertView 初始化一样,只是用RIButtonItem来代替原来的按钮标题,用RIButtonItem把action带上就省略了原来的delegate方法
2.这个方法则对应了 addButtonWithTitle 方法
重点来了,来看UIAlertView+Blocks.m的实现
#import "UIAlertView+Blocks.h"
#import <objc/runtime.h>
static NSString *RI_BUTTON_ASS_KEY = @"com.random-ideas.BUTTONS";
@implementation UIAlertView (Blocks)
-(id)initWithTitle:(NSString *)inTitle message:(NSString *)inMessage cancelButtonItem:(RIButtonItem *)inCancelButtonItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ...
{
if((self = [self initWithTitle:inTitle message:inMessage delegate:self cancelButtonTitle:inCancelButtonItem.label otherButtonTitles:nil]))
{
NSMutableArray *buttonsArray = [NSMutableArray array];
RIButtonItem *eachItem;
va_list argumentList; //1
if (inOtherButtonItems)
{
[buttonsArray addObject: inOtherButtonItems];
va_start(argumentList, inOtherButtonItems); //2
while((eachItem = va_arg(argumentList, RIButtonItem *))) //3
{
[buttonsArray addObject: eachItem];
}
va_end(argumentList); //4
}
for(RIButtonItem *item in buttonsArray)
{
[self addButtonWithTitle:item.label];
}
if(inCancelButtonItem)
[buttonsArray insertObject:inCancelButtonItem atIndex:0];
objc_setAssociatedObject(self, (const void *)RI_BUTTON_ASS_KEY, buttonsArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC); //5
[self setDelegate:self];
}
return self;
}
- (NSInteger)addButtonItem:(RIButtonItem *)item
{
NSMutableArray *buttonsArray = objc_getAssociatedObject(self, (const void *)RI_BUTTON_ASS_KEY);
NSInteger buttonIndex = [self addButtonWithTitle:item.label];
[buttonsArray addObject:item];
return buttonIndex;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
// If the button index is -1 it means we were dismissed with no selection
if (buttonIndex >= 0)
{
NSArray *buttonsArray = objc_getAssociatedObject(self, (const void *)RI_BUTTON_ASS_KEY); //6
RIButtonItem *item = [buttonsArray objectAtIndex:buttonIndex];
if(item.action)
item.action();
}
objc_setAssociatedObject(self, (const void *)RI_BUTTON_ASS_KEY, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); //7
}
@end
- va_list 是ios实现传递不定长的多个参数的方法时所使用的
- 然后用va_start初始化刚定义的va_list变量
- 然后用va_arg返回可变的参数,va_arg的第二个参数是你要返回的参数的类型.如果函数有多个可变参数的,依次调用va_arg获取各个参数;
下面就是如果还有其他的buttonItem就把它加到buttonsArray - 最后用va_end宏结束可变参数的获取。
- 因为在category里面不能添加成员变量,所以用objc_setAssociatedObject和objc_getAssociatedObject来变相的添加buttonArray方便下面delegate的时候取出buttonArray里的action
- 取出buttonArray,使用block来实现回调方法。
- set nil;
代码分析差不多,还学习了va_list 以后也能方便的使用这两个弹出框了。
上一个使用例子
敲下一块代码就出现了下面的弹框,很方便是不是。
iOS:简单使用UIAlertVIew和UIActionSheet的更多相关文章
- iOS 8 中 UIAlertView 和 UIActionSheet 河里去了?
iOS 8 中 UIAlertView 和 UIActionSheet 河里去了? 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商 ...
- iOS开发——UI篇Swift篇&UIAlertView/UIActionSheet
UIAlertView/UIActionSheet UIAlertView //一个按钮的提醒 @IBAction func oneButtonAler() { //创建单一按钮提醒视图 let on ...
- iOS8以后UIAlertView和UIActionSheet两种alert页面都将通过UIAlertController来创建
1. Important: UIAlertView is deprecated in iOS 8. (Note that UIAlertViewDelegate is also deprecated. ...
- iOS开发之UIAlertView与UIAlertController的详尽用法说明
本文将从四个方面对IOS开发中UIAlertView与UIAlertController的用法进行讲解: 一.UIAlertView与UIAlertController是什么东东? 二.我们为什么要用 ...
- UIAlertView、 UIActionSheet
一.UIAlertView. UIActionSheet都是ios系统自带的弹出式对话框,当UIAlertView或UIActionSheet弹出来时用户无法与应用界面中的其它控件交互,UIAlert ...
- UIAlertView、UIActionSheet兼容iOS8
链接地址:http://blog.csdn.net/nextstudio/article/details/39959895?utm_source=tuicool 1.前言 iOS8新增了UIAlert ...
- UIAlertView及UIActionSheet 在ios8极其以下版本的兼容问题解决方案
本文转载至 http://www.aichengxu.com/view/35326 UIAlertView及UIActionSheet在ios8中被放弃,其功能将完全由UIAlertControlle ...
- iOS 简单工厂模式
iOS 简单工厂模式 什么是简单工厂模式? 简单工厂模式中定义一个抽象类,抽象类中声明公共的特征及属性,抽象子类继承自抽象类,去实现具体的操作.工厂类根据外界需求,在工厂类中创建对应的抽象子类实例并传 ...
- 用block将UIAlertView与UIActionSheet统一起来
用block将UIAlertView与UIActionSheet统一起来 效果 1. 将代理方法的实例对象方法转换成了类方法使用 2. 要注意单例block不要长期持有,用完就释放掉 源码 https ...
随机推荐
- 【cocos2d-js官方文档】二十、moduleConfig.json
概述 该配置文件相当于v2版本号中的jsloader.js. 改造的目的是为了使得配置纯粹化,同一时候也能比較好的支持cocos-console.cocos-utils甚至是用户自己定义脚本工具. 字 ...
- Linux下FFmpeg的安装编译过程【转】
本文转载自:http://www.linuxidc.com/Linux/2013-06/85628.htm 详细说下在Linux下FFmpeg的安装编译过程.参考 Ubuntu 10.04安装编译FF ...
- CALayer初认识
CALayer :CA就是coreAnimation 核心动画 它是同时支持 Mac OS 和 iOS系统的 所有的核心动画都是通过CALayer来实现的 UIView本身是不具备显示功能的 是它内部 ...
- BZOJ 4321 DP
思路: 这个DP太神了- 完全没想到 http://blog.csdn.net/geotcbrl/article/details/49663401 //By SiriusRen #include &l ...
- P2740 [USACO4.2]草地排水Drainage Ditches
题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...
- UNP学习笔记3——基本UDP套接字编程
1 概述 TCP和UDP网络编程存在一些本质的差异,主要是由于传输层的差别:UDP是无连接的不可靠的数据报协议,而TCP是面向连接的字节流协议. 下图是典型的UDP客户端和服务器之间的通信流程.客户不 ...
- Functional programming-函数式编程
In computer science, functional programming is a programming paradigm—a style of building the struct ...
- 第四章 Python之文件处理
文件操作 文件操作一般分为三步:打开文件得到文件句柄并赋值给一个变量--->通过句柄对文件进行操作-->关闭文件 f=open(r'C:\Users\hesha\PycharmProjec ...
- 速学JavaScript!
什么是JavaScript? JavaScript是一种轻量级的脚本语言,也是一种嵌入式语言,是一种对象模型语言,简称JS:JavaScript的核心语法部分(语言本身)很精简,只包括两个部分: 基本 ...
- 阿里云数据库MySQL版快速上手!
MySQL是全球最受欢迎的开源数据库,其在各Web应用中均有广泛部署.阿里云数据库MySQL版基于Alibaba的MySQL源码分支,经过双11高并发.大数据量的考验,拥有优良的性能和吞吐量.除此之外 ...