永不过时的自定义AlertView

码农门都知道,再好的项目如果用户体验跟不上的话也就死了一半了,特别是网络这块,经常需要我们弹出各种提示框,这就需要用到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

时间: 2024-08-01 08:37:12

永不过时的自定义AlertView的相关文章

自定义AlertView实现模态对话框

在Windows应用程序中,经常使用模态(Model)对话框来和用户进行简单的交互,比如登录框.在IOS应用程序中,有时我们也希望做同样的事情.但IOS的UI库中,没有模态对话框,最接近那个样子的应该算是AlertView.但仅用AlertView,我们只能做文字提示,而不能和用户做交互. 本文将介绍如何基于AlertView做定制,实现模态对话框的功能.以密码修改框为例: 1. 首先,我们要继承AlertView类,在类的头文件PwdModifyView.h中,加入控件的声明    这里我们把

iOS自定义alertView,继承自UIView,可以添加子视图,标题图片+文字

自定义alertView,继承自UIView,可以在消息区域添加子视图:addCustomerSubview 标题可以有图片+文字构成, 只支持两个按钮操作 // - 在需要alert的控制器调用 alertView show 方法 CustomAlertView *alertView = [[CustomAlertView alloc] initWithTitle:@"提示" message:@"dylan_lwb_" delegate:self cancelBu

永不过时的股市格言

我们没有必要比别人更聪明,但我们必须比别人更有自制力. 投资者八”勤“:勤看,勤听,勤动,勤分析,勤比较,勤实践,勤总结,勤思考. 炒股如种粮,春播秋收冬藏鸡蛋不要放在一只篮子里投资进,投机出识马者长途,识险者长足吃鱼吃中段,头尾留别人人弃我取,人取我弃选质不如选时 割肉空仓,赚钱不慌进货靠消息,出货靠自己手中有股,心中无股新手怕大跌,老手怕大涨利好出尽是利空,利空出尽是利好行情在绝望中产生,行情在犹豫中发展,行情在欢乐中死亡横有多长,竖有多高守住30线,炒股不赔钱顶部3日,底部百天断头铡刀,逃

iOS开发——自定义AlertView

自定义的AlertView,可以选择出现的动画方式,特意做了几个可以对比.没啥难点,直接上代码,一看就懂. 1.在YYTAlertView.h文件中 // //  YYTAlertView.h //  Demo-自定义alertView // //  Created by yyt on 16/4/19. //  Copyright © 2016年 yyt. All rights reserved. // #import <UIKit/UIKit.h> typedef NS_ENUM(NSInt

Xcode自定义alertview

CustomIOS7AlertView *alert = [[CustomIOS7AlertViewalloc] init]; UIView *mainView = [[UIViewalloc] initWithFrame:CGRectMake(0,0, 280, 140)]; UIImageView *imgView = [[UIImageViewalloc] initWithFrame:CGRectMake(10,10, 20, 20)]; [imgViewsetImage:[UIImage

SQL 注入,永不过时的黑客技术

TalkTalk的信息泄漏事件导致约15万人的敏感信息被暴露,涉嫌造成这一事件的其中一名黑客使用的并不是很新的技术.事实上,该技术的「年纪」比这名15岁黑客还要大两岁. [译注:TalkTalk是英国电话和宽带供应商,这件信息安全事故发生在2015年10月份,当时这件事情还挺轰动的,上了新闻头条,其中一名黑客年仅15岁.] 这项技术就是大名鼎鼎的SQL注入,所谓SQL注入就是黑客在网站的提交表单数据中输入恶意命令从而获取数据的方法.它曾经被用来窃取世界卫生组织员工的信息,偷过华尔街日报数据,甚至

[转]Oracle DB 使用RMAN创建备份2

归档备份:概念 归档备份:概念 如果需要在指定时间内保留联机备份,RMAN 通常会假定用户可能需要在自执行该备份以来到现在之间的任意时间执行时间点恢复.为了满足这一要求,RMAN 会在此时段内保留归档日志.但是,可能仅需要在指定的时间(如两年)内保留特定备份(并使其保持一致和可恢复).用户不打算恢复到自执行该备份以后的某一时间点,只是希望能够正好恢复到执行该备份的确切时间.此外,用户还需要维护保留策略以使备份区井然有序,因此无法使备份恢复到两年前.为了满足保留数据的商业或法律要求,通常需要这么做

20 things i learned about browsers and the web

来源:我了解到的关于浏览器和网络的 20 件事 这是一本有Google chrome团队于2010年制作的电子书,由于在国内需要梯子..当一下搬运工 20 项须知:前言 如今许多人都离不开网络,我们只要动动手指就能获得全球信息,并且在瞬间接触到世界各地的人和活动. 所有这些超强体验都归功于开放的互联网.世界上的任何人都能通过任何已联网的设备,通过浏览器上网. 但是浏览器和网络的工作原理究竟是怎样的呢?万维网是如何发展到如今我们所了解和喜爱的样子的?我们需要了解哪些事情才能安全有效地浏览网络? "

十年架构师留下最完整的Java学习路线,学完年薪40W

文章有点长,请大家耐心看完,话不多说直接上干货! 永不过时的编程语言--Java 编程开发. Java编程语言占比: 据官方数据统计,在全球编程语言工程师的数量上,Java编程语言以900万的程序员数量位居首位. 而且很多软件的开发都离不开Java编程,因此其程序员的数量最多.而在以Java编程为核心的开发领域中,javaEE程序员的需求量10年来一直居于首位!创一个小群,供大家学习交流聊天如果有对学java方面有什么疑惑问题的,或者有什么想说的想聊的大家可以一起交流学习一起进步呀.也希望大家对