带有关闭按钮的alertView
概述
详细
一、程序实现
1、程序结构

2、实现思路与代码
XBAlertView是作为显示弹出框的入口,在初始化XBAlertView示例时,会将弹出框除了按钮部分全都设置好。而按钮部分采用UICollectionView来实现(因为有可能有多个按钮,这样方便扩展)。
- (void)setupContentView{
    //title
    self.alertTitleLabel = [[UILabel alloc] init];
    self.alertTitleLabel.font = [UIFont boldSystemFontOfSize:17.0f];
    self.alertTitleLabel.textAlignment = NSTextAlignmentCenter;
    self.alertTitleLabel.frame = CGRectMake(TitleHorizontalOffset, TitleMarginTop, SelfWidth - TitleHorizontalOffset * 2, self.alertTitleLabel.font.lineHeight);
    [self addSubview:self.alertTitleLabel];
    //content
    CGFloat contentLabelWidth = SelfWidth - ContentHorizontalOffset * 2;
    CGFloat contentH = [self heightWithContent:_content byWidth:contentLabelWidth andFontSize:13 andLineSpacing:3];
    self.alertContentLabel = [[UILabel alloc] initWithFrame:CGRectMake(ContentHorizontalOffset, CGRectGetMaxY(self.alertTitleLabel.frame) + ContentMarginTop, contentLabelWidth, contentH)];
    self.alertContentLabel.numberOfLines = 0;
    self.alertContentLabel.textAlignment = NSTextAlignmentCenter;
    self.alertContentLabel.font = [UIFont systemFontOfSize:13.0f];
    [self addSubview:self.alertContentLabel];
    //self
    CGFloat selfHeight = TitleMarginTop + self.alertTitleLabel.font.lineHeight + ContentMarginTop + contentH + BtnMarginTop + kButtonHeight;
    CGFloat selfMarginLeft = (ScreenWidth - SelfWidth) / 2;
    self.frame = CGRectMake(selfMarginLeft, (ScreenHeight - selfHeight) / 2, SelfWidth, selfHeight);
    self.clipsToBounds = YES;
    self.layer.cornerRadius = 10.0;
    self.backgroundColor = [UIColor whiteColor];
    //collectionView
    [self addSubview:self.collectionView];
    _collectionView.delegate = self;
    _collectionView.dataSource = self;
    [_collectionView registerNib:[UINib nibWithNibName:@"XBAlertBtnCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:btnCellOneID];
    [_collectionView registerNib:[UINib nibWithNibName:@"XBAlertBtnCellTwo" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:btnCellTwoID];
    //X按钮
    UIButton *xButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [xButton setImage:[UIImage imageNamed:@"btn_close_normal.png"] forState:UIControlStateNormal];
    [xButton setImage:[UIImage imageNamed:@"btn_close_selected.png"] forState:UIControlStateHighlighted];
    xButton.frame = CGRectMake(self.frame.size.width - 32, 0, 32, 32);
    [self addSubview:xButton];
    [xButton addTarget:self action:@selector(dismissAlert) forControlEvents:UIControlEventTouchUpInside];
}
为了能够切合原生方式的调用,提供了-(void)addAction:(dispatch_block_t)actionBlock withTitle:(NSString*)title方法,该方法用于向XBAlertView添加按钮以及对应的响应block。
-(void)addAction:(dispatch_block_t)actionBlock withTitle:(NSString*)title{
    if(actionBlock && ![self isBlankString:title]){
        [self.blockArray addObject:actionBlock];
        [self.btnTitleArray addObject:title];
    }
}
调用后会先保存到数组当中。
在这之后,调用方调用XBAlertView的show方法进行展示。
- (void)show
{
if(self.btnTitleArray.count == 0 || self.btnTitleArray.count > 2){
//更新view的frame
[self updateFrame];
}
[self.collectionView reloadData];
UIViewController *topVC = [self appRootViewController];
[topVC.view addSubview:self];
}
show方法首先会根据两个数组是否有值来决定是否更新collectionView的frame。之后调用collectionView的reloadData,数据源就是这两个数组。这样加载后collectionView就有了需要展示的按钮。
然后获取[UIApplication sharedApplication].keyWindow.rootViewController,在这个控制器的view上添加上已经布局好的XBAlertView。
但是为了营造阴影效果,在XBAlertView被添加到父view之前,会调用以下方法创建一个遮罩层。这样就能达到显示的要求。
- (void)willMoveToSuperview:(UIView *)newSuperview
{
if (newSuperview == nil) {
return;
}
UIViewController *topVC = [self appRootViewController]; if (!self.backImageView) {
self.backImageView = [[UIView alloc] initWithFrame:topVC.view.bounds];
self.backImageView.backgroundColor = [UIColor blackColor];
self.backImageView.alpha = 0.6f;
self.backImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
}
[topVC.view addSubview:self.backImageView];
CGRect afterFrame = CGRectMake((CGRectGetWidth(topVC.view.bounds) - self.frame.size.width) * 0.5, (CGRectGetHeight(topVC.view.bounds) - self.frame.size.height) * 0.5, self.frame.size.width, self.frame.size.height);
self.frame = afterFrame;
[super willMoveToSuperview:newSuperview];
}
那么接下来就是点击响应了,因为每个按钮就是collectionView的一个cell,所以按钮的点击就转为了cell的didSelectItemAtIndexPath方法。在该方法中根据索引从前面保存好的数组取出相对应的block,并调用
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    dispatch_block_t block = self.blockArray[indexPath.row];
    block();
    [self dismissAlert];
}
那么为了将隐藏弹出框封装到里面,会主动调用dismissAlert方法隐藏弹出框。
二、运行效果
下载解压后,直接用xcode打开,即可运行



注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
带有关闭按钮的alertView的更多相关文章
- 自定义带有uitableview的alertview对话框
		
#import <UIKit/UIKit.h> typedef void(^MyCompleteHandler) (NSString *selectString); @interface ...
 - jbox使用总结
		
jbox是一个不错的插件 当使用get打开新页面的时候,可以使用h.对像ID来获得对像ID的值 Js代码 js代码: /** * @description: test * @author: BrinP ...
 - bootstrap学习之二-组件
		
一.bootstrap字体图标 以span的形式出现,通常可以用于一个button或者其他元素的内文本, <span class="glyphicon glyphicon-sort-b ...
 - 转--2014年最新810多套android源码2.46GB免费一次性打包下载
		
转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源 ...
 - 2014年最新720多套Android源码2.0GB免费一次性打包下载
		
之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共 ...
 - Bootstrap警告框
		
前面的话 在网站中,网页总是需要和用户一起做沟通与交流.特别是当用户操作上下文为用户提供一些有效的警示框,比如说告诉用户操作成功.操作错误.提示或者警告等.在Bootstrap框架有一个独立的组件,实 ...
 - SCLAlertView-Swift
		
SCLAlertView-Swift https://github.com/vikmeup/SCLAlertView-Swift Animated Alert View written in Sw ...
 - Bootstrap学习-其它内置组件
		
1.缩略图(一) 缩略图在网站中最常用的地方就是产品列表页面,一行显示几张图片,有的在图片底下(左侧或右侧)带有标题.描述等信息.Bootstrap框架将这一部独立成一个模块组件.并通过“thumbn ...
 - Bootstrap-other内置组件
		
1.缩略图 缩略图在网站中最常用的地方就是产品列表页面,一行显示几张图片,有的在图片底下(左侧或右侧)带有标题.描述等信息.Bootstrap框架将这一部独立成一个模块组件.并通过“thumbnail ...
 
随机推荐
- IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) B. Bear and Compressing 暴力
			
B. Bear and Compressing 题目连接: http://www.codeforces.com/contest/653/problem/B Description Limak is a ...
 - 也谈时间管理和GTD
			
也谈时间管理和GTD 时间管理 随着事情越来约多发现时间越来越不够用了,但是其实每天时间都是恒定的,并不增也不减,所以感觉时间不够用了总归只是个人主观感觉. 对我个人帮助比较大的是三本书<番茄时 ...
 - JQ自定义下拉列表插件
			
自从上次做了JQ自定义分页插件和表格插件后,就没在自定义过插件了,这一个月都在用linq和ef,基本前端都没怎么去碰了,今天有个同事说有个项目需要在下拉框里面带有复选框,本来想网上找下插件的,一想,其 ...
 - J-LINK序列号修改
			
打开J-LINK COMMANDER中输入 exec setsn=xxxxxxxx 即可
 - Unity 网络请求(1)
			
using UnityEngine; using System.Collections; public class Scene1 : MonoBehaviour { //下载图片的容器 private ...
 - NHibernate Configuring
			
NHibernate引用程序中有几个关键组件,如下图所示: 初始化时,NHibernate应用程序将生成一个配置对象.本节中,我们通过设置App.config文件来生成该配置对象.该对象负责加载映射信 ...
 - Java操作Microsoft Word之jacob
			
转自: 现在我们一起来看看,用Java如何操作Microsoft Word. jacob,官网是http://danadler.com/jacob 这是一个开源的工具.最新版本1.7 官方 ...
 - vi命令用法
			
从shell中启动可视化编辑器vi filename指示shell启动vi编辑器,并将参数filename传给它.如果当前目前中存在该文件,则vi编辑器将它解释为要打开的文件:如果没有该文件,则vi编 ...
 - C++keyword大总结
			
register: 假设有一些变量使用频繁,则为存取变量的值少花一些时间, 能够将该局部变量的值放在CPU的寄存器中,须要时直接从寄存器 中取出參加运算,不必去内存中去存取. 由于寄存器的存取速度 远 ...
 - iOS:Xcode7以上版本安装镜像文件.dmg
			
Xcode:7.0~7.3的镜像如下,点击直接下载安装 xcode7.0:https://developer.apple.com/services-account/download?path=/Dev ...