您的位置:首页 > 其它

永不过时的自定义AlertView

2016-06-11 18:56 295 查看
码农门都知道,再好的项目如果用户体验跟不上的话也就死了一半了,特别是网络这块,经常需要我们弹出各种提示框,这就需要用到alertView了,但是ios8以后alertView就被alertController替代了 而项目中用我们又经常需要用到它,今天笔者就为大家带来一个可以显著提升用户体验度,直接继承至UIWindow的高度自定义AlertView(永不过时),希望大家喜欢!废话不多说,直接上代码

.h文件如下

//
//  Prompt.h
//  CustomAlertView
//
//  Created by jacke-xu on 16/6/4.
//  Copyright © 2016年 jacke-xu. All rights reserved.
//

#import <UIKit/UIKit.h>

//点击样式
typedef NS_ENUM(NSInteger, MyWindowClick){

MyWindowClickForOK = 0,//点击确定按钮

MyWindowClickForCancel//点击取消按钮
};

//提示框显示样式
typedef NS_ENUM(NSInteger, PromptStyle)
{

PromptStyleDefalut = 0,//默认样式 ——成功

PromptStyleSuccess,//成功

PromptStyleFail,//失败

PromptStyleWaring//警告
};

typedef void (^callBack)(MyWindowClick buttonIndex);

@interface Prompt : UIWindow

@property (nonatomic, copy) callBack clickBlock ;//按钮点击事件的回调

+ (instancetype)shared;

/**
*  创建Prompt并展示
*
*  @param style    绘制的图片样式
*  @param title    警示标题
*  @param detail   警示内容
*  @param canle    取消按钮标题
*  @param ok       确定按钮标题
*  @param callBack 按钮点击时间回调
*
*  @return 返回Prompt
*/
+ (instancetype)showPromptWithStyle:(PromptStyle)style title:(NSString *)title detail:(NSString *)detail canleButtonTitle:(NSString *)canle okButtonTitle:(NSString *)ok callBlock:(callBack)callBack;

//默认样式创建Prompt
+ (instancetype)showPromptWithTitle:(NSString *)title detail:(NSString *)detail canleButtonTitle:(NSString *)canle okButtonTitle:(NSString *)ok callBlock:(callBack)callBack;

@end


再来.m

//
//  Prompt.m
//  CustomAlertView
//
//  Created by jacke-xu on 16/6/4.
//  Copyright © 2016年 jacke-xu. All rights reserved.
//

#import "Prompt.h"

//按钮颜色
#define OKBUTTON_BGCOLOR [UIColor colorWithRed:158/255.0 green:214/255.0 blue:243/255.0 alpha:1]
#define CANCELBUTTON_BGCOLOR [UIColor colorWithRed:255/255.0 green:20/255.0 blue:20/255.0 alpha:1]
//按钮起始tag
#define TAG 100

#define SCREEN_Width   [UIScreen mainScreen].bounds.size.width
#define SCREEN_Height   [UIScreen mainScreen].bounds.size.height

NSUInteger const Button_Size_Width = 80;
NSUInteger const Button_Size_Height = 30;

NSInteger const Title_Font = 18;
NSInteger const Detial_Font = 16;

//Logo半径(画布)
NSInteger const Logo_Size = 40;

NSInteger const Button_Font = 16;

@interface Prompt () {

UIView * _logoView;//画布
UILabel * _titleLabel;//标题
UILabel * _detailLabel;//详情

UIButton * _OkButton;//确定按钮
UIButton * _canleButton;//取消按钮

CAShapeLayer * _pathLayer;//尝试保护内存
}

@end

@implementation Prompt

+ (instancetype)showPromptWithStyle:(PromptStyle)style title:(NSString *)title detail:(NSString *)detail canleButtonTitle:(NSString *)canle okButtonTitle:(NSString *)ok callBlock:(callBack)callBack {

switch (style) {
case PromptStyleDefalut:
[[self shared] drawRight];
break;
case PromptStyleSuccess:
[[self shared] drawRight];

break;
case PromptStyleFail:
[[self shared] drawWrong];

break;
case PromptStyleWaring:
[[self shared] drawWaring];

break;
default:
break;
}
[[self shared] addButtonTitleWithCancle:canle OK:ok];
[[self shared] addTitle:title detail:detail];
[[self shared] setClickBlock:nil];//释放掉之前的Block
[[self shared] setClickBlock:callBack];
[[self shared] setHidden:NO];//设置为不隐藏
return  [self shared];
}

+ (instancetype)showPromptWithTitle:(NSString *)title detail:(NSString *)detail canleButtonTitle:(NSString *)canle okButtonTitle:(NSString *)ok callBlock:(callBack)callBack {

return [self showPromptWithStyle:PromptStyleSuccess title:title detail:detail canleButtonTitle:canle okButtonTitle:ok callBlock:callBack];
}

//单例
+ (instancetype)shared
{
static dispatch_once_t once = 0;
static Prompt *prompt;
dispatch_once(&once, ^{
prompt = [[Prompt alloc] init];
});
return prompt;
}

- (instancetype)init
{
self = [super init];
if (self) {
self.frame = (CGRect) {{0.f,0.f}, [[UIScreen mainScreen] bounds].size};
self.alpha = 1;
[self setBackgroundColor:[UIColor clearColor]];
self.hidden = NO;//不隐藏
self.windowLevel = 100;

[self setInterFace];
}

return self;
}
/**
*  界面初始化
*/
- (void)setInterFace
{
[self logoInit];
[self controlsInit];
}
/**
*  初始化控件
*/
- (void)controlsInit
{
CGFloat x = _logoView.frame.origin.x;
CGFloat y = _logoView.frame.origin.y;
CGFloat height = _logoView.frame.size.height;
CGFloat width = _logoView.frame.size.width;

_titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(x ,y + height / 2, width, Title_Font + 5)];
[_titleLabel setFont:[UIFont systemFontOfSize:Title_Font]];
[_titleLabel setTextAlignment:NSTextAlignmentCenter];

_detailLabel  = [[UILabel alloc] initWithFrame:CGRectMake(x ,y + height / 2 + (Title_Font + 10), width, Detial_Font + 5)];
_detailLabel.textColor = [UIColor grayColor];
[_detailLabel setFont:[UIFont systemFontOfSize:Detial_Font]];
[_detailLabel setTextAlignment:NSTextAlignmentCenter];

CGFloat centerY = _detailLabel.center.y + 40;

_OkButton = [UIButton buttonWithType:UIButtonTypeCustom];
_OkButton.layer.cornerRadius = 5;
_OkButton.titleLabel.font = [UIFont systemFontOfSize:Button_Font];
_OkButton.center = CGPointMake(_detailLabel.center.x + 50, centerY);
_OkButton.bounds = CGRectMake(0, 0, Button_Size_Width, Button_Size_Height);
_OkButton.backgroundColor = OKBUTTON_BGCOLOR;

_canleButton = [UIButton buttonWithType:UIButtonTypeCustom];
_canleButton.center = CGPointMake(_detailLabel.center.x - 50, centerY);
_canleButton.bounds = CGRectMake(0, 0, Button_Size_Width, Button_Size_Height);
_canleButton.backgroundColor = CANCELBUTTON_BGCOLOR;
_canleButton.layer.cornerRadius = 5;
_canleButton.titleLabel.font = [UIFont systemFontOfSize:Button_Font];

[self addSubview:_titleLabel];
[self addSubview:_detailLabel];
[self addSubview:_OkButton];
[self addSubview:_canleButton];

_canleButton.hidden = YES;
_OkButton.hidden = YES;

_OkButton.tag = TAG;
_canleButton.tag = TAG + 1;

[_OkButton addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[_canleButton addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];

}

/**
*  初始化logo视图——画布
*/
// 需完善画布的清除,不适用移除,新建的办法
- (void)logoInit
{
//移除画布
[_logoView removeFromSuperview];
_logoView = nil;
//新建画布
_logoView                     = [UIView new];
_logoView.center              = CGPointMake(self.center.x, self.center.y - 40);
_logoView.bounds              = CGRectMake(0, 0, 320 / 1.5, 320 / 1.5);
_logoView.backgroundColor     = [UIColor whiteColor];
_logoView.layer.cornerRadius  = 10;
_logoView.layer.shadowColor   = [UIColor blackColor].CGColor;
_logoView.layer.shadowOffset  = CGSizeMake(0, 5);
_logoView.layer.shadowOpacity = 0.3f;
_logoView.layer.shadowRadius  = 10.0f;

//保证画布位于所有视图层级的最下方
if (_titleLabel != nil) {
[self insertSubview:_logoView belowSubview:_titleLabel];
}
else
[self addSubview:_logoView];
}
/**
*  添加按钮
*
*  @param cancle 按钮标题
*  @param ok     按钮标题
*/
- (void) addButtonTitleWithCancle:(NSString *)cancle OK:(NSString *)ok
{
BOOL flag = NO;
if (cancle == nil && ok != nil ) {
flag = YES;
}

CGFloat centerY = _detailLabel.center.y + 40;

if (flag) {
_OkButton.center = CGPointMake(_detailLabel.center.x, centerY);
_OkButton.bounds = CGRectMake(0, 0, Button_Size_Width, Button_Size_Height);
_canleButton.hidden = YES;

}
else
{
_canleButton.hidden = NO;
[_canleButton setTitle:cancle forState:UIControlStateNormal];
_OkButton.center = CGPointMake(_detailLabel.center.x + 50, centerY);
_OkButton.bounds = CGRectMake(0, 0, Button_Size_Width, Button_Size_Height);
}
_OkButton.hidden = NO;
[_OkButton setTitle:ok forState:UIControlStateNormal];
}
/**
*  添加标题信息和详细信息
*
*  @param title  标题内容
*  @param detail 详细内容
*/
- (void)addTitle:(NSString *)title detail:(NSString *)detail
{
_titleLabel.text  = title;
_detailLabel.text = detail;
}

/**
*  画圆和勾
*/
-(void) drawRight
{

[self logoInit];
//自绘制图标中心点
CGPoint pathCenter = CGPointMake(_logoView.frame.size.width/2, _logoView.frame.size.height/2 - 50);
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:pathCenter radius:Logo_Size startAngle:0 endAngle:M_PI*2 clockwise:YES];

path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineCapRound;

CGFloat x = _logoView.frame.size.width/2.5 + 5;
CGFloat y = _logoView.frame.size.height/2 - 45;
//勾的起点
[path moveToPoint:CGPointMake(x, y)];
//勾的最底端
CGPoint p1 = CGPointMake(x+10, y+ 10);
[path addLineToPoint:p1];
//勾的最上端
CGPoint p2 = CGPointMake(x+35,y-20);
[path addLineToPoint:p2];
//新建图层——绘制上面的圆圈和勾
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = [UIColor greenColor].CGColor;
layer.lineWidth = 5;
layer.path = path.CGPath;

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))];
animation.fromValue = @0;
animation.toValue = @1;
animation.duration = 0.5;
[layer addAnimation:animation forKey:NSStringFromSelector(@selector(strokeEnd))];

[_logoView.layer addSublayer:layer];

}

/**
*  画三角形以及感叹号
*/
-(void) drawWaring
{

//    [_logoView removeFromSuperview];
[self logoInit];
//自绘制图标中心店
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineCapRound;

//绘制三角形
CGFloat x = _logoView.frame.size.width/2;
CGFloat y = 15;
//三角形起点(上方)
[path moveToPoint:CGPointMake(x, y)];
//左边
CGPoint p1 = CGPointMake(x - 45, y + 80);
[path addLineToPoint:p1];
//右边
CGPoint p2 = CGPointMake(x + 45,y + 80);
[path addLineToPoint:p2];
//关闭路径
[path closePath];

//绘制感叹号
//绘制直线
[path moveToPoint:CGPointMake(x, y + 20)];
CGPoint p4 = CGPointMake(x, y + 60);
[path addLineToPoint:p4];
//绘制实心圆
[path moveToPoint:CGPointMake(x, y + 70)];
[path addArcWithCenter:CGPointMake(x, y + 70) radius:2 startAngle:0 endAngle:M_PI*2 clockwise:YES];

//新建图层——绘制上述路径
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = [UIColor orangeColor].CGColor;
layer.lineWidth = 5;
layer.path = path.CGPath;

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))];
animation.fromValue = @0;
animation.toValue = @1;
animation.duration = 0.5;
[layer addAnimation:animation forKey:NSStringFromSelector(@selector(strokeEnd))];

[_logoView.layer addSublayer:layer];
}

/**
*  画圆角矩形和叉
*/
- (void)drawWrong
{

[self logoInit];

CGFloat x = _logoView.frame.size.width / 2 - Logo_Size;
CGFloat y = 15;

//圆角矩形
UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(x, y, Logo_Size * 2, Logo_Size * 2) cornerRadius:5];
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineCapRound;

CGFloat space = 20;
//斜线1
[path moveToPoint:CGPointMake(x + space, y + space)];
CGPoint p1 = CGPointMake(x + Logo_Size * 2 - space, y + Logo_Size * 2 - space);
[path addLineToPoint:p1];
//斜线2
[path moveToPoint:CGPointMake(x + Logo_Size * 2 - space , y + space)];
CGPoint p2 = CGPointMake(x + space, y + Logo_Size * 2 - space);
[path addLineToPoint:p2];

//新建图层——绘制上述路径
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
layer.fillColor = [UIColor clearColor].CGColor;
layer.strokeColor = [UIColor redColor].CGColor;
layer.lineWidth = 5;
layer.path = path.CGPath;
//使用NSStringFromSelector(@selector(strokeEnd))作为KeyPath的作用,绘制动画每一次Show均重复运行
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))];
animation.fromValue = @0;
animation.toValue = @1;
animation.duration = 0.5;
//和上对应
[layer addAnimation:animation forKey:NSStringFromSelector(@selector(strokeEnd))];

[_logoView.layer addSublayer:layer];
}

/**
*
*  按钮点击事件
*
*  @param sender 按钮
*/
- (void)buttonClick:(UIButton *)sender
{
self.clickBlock(sender.tag - TAG);
}

@end


调用方法:

//
//  ViewController.m
//  CustomAlertView
//
//  Created by jacke-xu on 16/6/4.
//  Copyright © 2016年 jacke-xu. All rights reserved.
//

#import "ViewController.h"
#import "Prompt.h"

@interface ViewController ()
{
UIWindow *__sheetWindow;//window必须为全局变量或成员变量
}

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

self.view.backgroundColor = [UIColor whiteColor];

CGFloat x = self.view.center.x ;
CGFloat y = self.view.center.y - 200;

NSArray * textArray = @[@"成功",@"失败",@"警告"];

for (NSUInteger i = 0; i < 3 ; i ++) {
UIButton * successButton = [UIButton buttonWithType:UIButtonTypeSystem];
[successButton setTitle:textArray[i] forState:UIControlStateNormal];
successButton.center  = CGPointMake(x, y);
successButton.bounds = CGRectMake(0, 0, 100, 30);
[self.view addSubview:successButton];
[successButton addTarget:self action:@selector(show:) forControlEvents:UIControlEventTouchUpInside];
successButton.tag = 60 + i;
y += 60;
}
}

- (void)show:(UIButton *)sender
{

NSString * title = nil;
NSString * detail = nil;
NSString * cancle = @"取消";
NSString * ok = @"确定";
switch (sender.tag - 59) {
case PromptStyleSuccess:
case PromptStyleDefalut:
title = @"温馨提示";
detail = @"登录成功";
cancle = nil;
break;
case PromptStyleFail:
title = @"错误提示";
detail = @"您输入的号码有误。";
break;
case PromptStyleWaring:
title = @"警告";
detail = @"您正在进行非安全操作!!";
default:
break;
}
//为成员变量Window赋值则立即显示Window
__sheetWindow = [Prompt showPromptWithStyle:sender.tag - 59 title:title detail:detail canleButtonTitle:cancle okButtonTitle:ok callBlock:^(MyWindowClick buttonIndex) {

//Window隐藏,并置为nil,释放内存 不能少
NSLog(@"用户点击了第%ld个按钮",(long)buttonIndex);
__sheetWindow.hidden = YES;
__sheetWindow = nil;

}];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end


项目源码请见 GitHub: https://github.com/Jacke-xu/CustomAlertView
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: