【记录】【完整代码最下】

效果如下:

可行性分析:

由于系统自带的UIAlertView样式简单,只有两种样式,想要理想的样式就要自定义控件了

文件名取为:CustomAlertView

创建文件如下(大型项目最好把全部的view都放进一个group中)

接下来要定义AlertView的界面,用xib来直接拖取控件更加方便

1.创建xib文件

文件名要跟类名一致(方便操作)

2.在xib文件里面直接拖取控件

对应的就是这样子 ,把对应的控件名称改成能够清楚看出来的

因为是模仿系统的样式,布局了左右btn样式和上下btn

3.修改class的值为类名 两个都要

4.将如图框起来的view的背景色改成

5.效果图中的提示框圆角效果

这个效果在xib中设置,要选中这后面的view

属性名称:layer.cornerRadius

6.在CustomAlertView类中定义一个类方法

这个类方法是一个对外的接口,当外部要使用自定义类创建一个框架时就可以直接调用。

因为我在xib文件里面的创建视图的顺序是先 上下型 再左右型的,因此可以枚举出两种类型的视图。

 1 #import <UIKit/UIKit.h>
2
3 typedef enum{
4 kCustomAlertViewSytleUpAndDown,//默认=0
5 kCustomAlertViewSytleLeftAndRight//默认=1
6 }kCustomAlertViewSytle;
7
8
9 @interface CustomAlertView : UIView
10
11 +(CustomAlertView *)alertViewWithImagename:(NSString *)imgName andTitle:(NSString *)title andSytle:(kCustomAlertViewSytle)sytle;
12
13
14
15 @end 

7.在CustomAlertView.m文件中读取xib中的自定义控件视图

定义了类方法,下一步在.m文件中实现方法,在实现方法过程中发现要用到xib中的控件属性

因此,在xib中拖属性添加在CustomAlertView.m文件中

虽然我在xib中创建的视图是两套,但是其中的控件都是一一对应的,因此每个属性可以关联两个控件(这是特殊情况,一般一个xib只创建一个视图)

接下来读取xib文件。用到的方法是

- (nullable NSArray *)loadNibNamed:(NSString *)name owner:(nullable id)owner options:(nullable NSDictionary *)options;

注意到,这个方法读出来的返回值是一个数组,xib文件中如果有多个视图,那么读出来数组的顺序就跟下图的顺序一样。

实现代码如下:

 1 +(CustomAlertView *)alertViewWithImagename:(NSString *)imgName andTitle:(NSString *)title andSytle:(kCustomAlertViewSytle)sytle{
2 //从xib中读取视图数组
3 NSArray *arr = [[NSBundle mainBundle]loadNibNamed:@"CustomAlertView" owner:nil options:nil];
4 //根据sytle值读取数组中的第几个
5 CustomAlertView *aCAV = [arr objectAtIndex:sytle];
6 //把传过来的图片名称和标题名称赋值
7 //要先判断是否为空。若为空则默认xib中已设置的
8 if (imgName != nil) {
9 [aCAV.iconImageView setImage:[UIImage imageNamed:imgName]];
10 }
11 if (title != nil) {
12 [aCAV.titleLabel setText:title];
13 }
14
15
16 return aCAV;
17 }

8.让自定义提示框显示在界面上和消失(这里还没有给提示框的按钮设置事件)

显示界面有两种方法,一种是在创建完对象给一个参数值,再在方法实现中让addsubview,这种方法的实现相对简单。

实现代码如下:

1 -(void)showInView:(UIView *)fatherView{
2 [fatherView addSubview:self];
3 }

这种方法相对简单,作为一个自己使用的类来说是足够用的。但如果作为一个可导入的第三方工具类来说,就有点麻烦了。

如果能直接用一个方法就能让提示框显示在界面上肯定是更加方便,例如 [self show];

(其实我这里也没有理解清楚appdelegate)

***记得导入#import "AppDelegate.h"

 1 - (void)show{
2 // 将这个视图添加到当前界面的最外层
3 // 找到当前的这个界面
4 // UIWindow -> 添加视图
5 // 1.找到应用程序唯一的代理对象AppDelegate
6 AppDelegate *appD = (AppDelegate *)[UIApplication sharedApplication].delegate;
7 //
8 // 2.获取程序的窗口
9 self.frame = [UIScreen mainScreen].bounds;
10 [appD.window addSubview:self];
11 }

还有一种:

 1 -(void)show{
2
3 //找到当前这个界面的那个视图
4 //UIWindow->rootViewController->UIView ->添加视图
5 //1.找到应用程序的代理对象
6 AppDelegate *appD = (AppDelegate *)[UIApplication sharedApplication].delegate;
7
8 //2.找到窗口默认控制的那个根视图控制器
9 UIViewController *rootVC = appD.window.rootViewController;
10
11 //3.在这个控制器的视图上面添加一个子视图
12 self.frame = rootVC.view.bounds;
13 [rootVC.view addSubview:self];
14
15
16
17 }

消失:

1 - (void)dismiss{
2 [self removeFromSuperview];
3 }

这里先运行一下,在ViewController.m中任意创建图片

1 - (void)viewDidLoad {
2 [super viewDidLoad];
3 // Do any additional setup after loading the view, typically from a nib.
4 UIImageView *imgview = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"tree"]];
5 imgview.frame = self.view.bounds;
6 [self.view addSubview:imgview];
7 }
1 -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
2 CustomAlertView *alertView = [CustomAlertView alertViewWithImagename:@"ok" andTitle:@"吃了吗" andSytle:kCustomAlertViewSytleUpAndDown];
3
4 [alertView show];
5
6 }

还没设置按钮点击事件因此不会有反应。

9.接下来设置按钮的点击事件

创建的自定义提示框的按钮的title要可以改变,也可以在点击完按钮之后再完成点别的事件。

因为完成 这些事 是要在按钮被点击后执行的,因此 这些事的执行代码 应该在btndidclicked方法里面。

所以,要有2个block来保存数据,等到点击按钮的时候再执行。(也可以用通知或者delegate来做)

1 //定义两个block 用于接收外部传递过来的block的类型
2 typedef void (^SureBtnBlock)(void);
3 typedef void (^CancelBtnBlock)(void);
1 -(void)setSureBtnWithTitle:(NSString *)title andComlished:(SureBtnBlock)sureblock;
2
3 -(void)setCancelBtnWithTitle:(NSString *)title andComlished:(CancelBtnBlock)cancelblock;
 1 -(void)setSureBtnWithTitle:(NSString *)title andComlished:(SureBtnBlock)sureblock{
2 //这里判断一下外部是否传title值
3 if (title != nil) {
4 [self.sureBtn setTitle:title forState:UIControlStateNormal];
5 }
6 //这里发现要用一个属性变量来保存住外部传过来的sureblock
7 self.sureblock = sureblock;
8 }
9
10 -(void)setCancelBtnWithTitle:(NSString *)title andComlished:(CancelBtnBlock)cancelblock{
11 if (title != nil) {
12 [self.cancelBtn setTitle:title forState:UIControlStateNormal];
13 }
14
15 self.cancelblock = cancelblock;
16
17
18
19 }
1 //block 用copy
2 @property (nonatomic , copy) SureBtnBlock sureblock;
3
4 @property (nonatomic , copy) CancelBtnBlock cancelblock;

根据上面的分析,在btn的点击事件中执行外部传来的block

 1 - (IBAction)sureBTNdidClicked:(id)sender {
2 //先让提示框消失
3 [self dismiss];
4 //执行一下block
5 self.sureblock();
6 }
7
8
9
10 - (IBAction)cancelBTNdidClicked:(id)sender {
11 //先让提示框消失
12 [self dismiss];
13 //执行一下block
14 self.cancelblock();
15
16 }

接下来我在viewcontroller的触摸事件中配置了提示框

效果如下:

附源代码

 1 //
2 // CustomAlertView.h
3 // 0310--自定义框架
4 //
5 // Created by MyMac on 2019/3/12.
6 // Copyright 2019年 MyMac. All rights reserved.
7 //
8
9 #import <UIKit/UIKit.h>
10 //定义两个block 用于接收外部传递过来的block的类型
11 typedef void (^SureBtnBlock)(void);
12 typedef void (^CancelBtnBlock)(void);
13
14
15 typedef enum{
16 kCustomAlertViewSytleUpAndDown,
17 kCustomAlertViewSytleLeftAndRight
18 }kCustomAlertViewSytle;
19
20
21 @interface CustomAlertView : UIView
22
23 +(CustomAlertView *)alertViewWithImagename:(NSString *)imgName andTitle:(NSString *)title andSytle:(kCustomAlertViewSytle)sytle;
24
25 -(void)show;
26
27 -(void)dismiss;
28
29 -(void)setSureBtnWithTitle:(NSString *)title andComlished:(SureBtnBlock)sureblock;
30
31 -(void)setCancelBtnWithTitle:(NSString *)title andComlished:(CancelBtnBlock)cancelblock;
32
33
34
35 @end
  1 //
2 // CustomAlertView.m
3 // 0310--自定义框架
4 //
5 // Created by MyMac on 2019/3/12.
6 // Copyright 2019年 MyMac. All rights reserved.
7 //
8
9 #import "CustomAlertView.h"
10 #import "AppDelegate.h"
11 @interface CustomAlertView()
12 @property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
13
14 @property (weak, nonatomic) IBOutlet UILabel *titleLabel;
15
16 @property (weak, nonatomic) IBOutlet UIButton *sureBtn;
17
18 @property (weak, nonatomic) IBOutlet UIButton *cancelBtn;
19
20 //block 用copy
21 @property (nonatomic , copy) SureBtnBlock sureblock;
22
23 @property (nonatomic , copy) CancelBtnBlock cancelblock;
24 @end
25
26
27
28 @implementation CustomAlertView
29 +(CustomAlertView *)alertViewWithImagename:(NSString *)imgName andTitle:(NSString *)title andSytle:(kCustomAlertViewSytle)sytle{
30 //从xib中读取视图数组
31 NSArray *arr = [[NSBundle mainBundle]loadNibNamed:@"CustomAlertView" owner:nil options:nil];
32 //根据sytle值读取数组中的第几个
33 CustomAlertView *aCAV = [arr objectAtIndex:sytle];
34 //把传过来的图片名称和标题名称赋值
35 //要先判断是否为空。若为空则默认xib中已设置的
36 if (imgName != nil) {
37 [aCAV.iconImageView setImage:[UIImage imageNamed:imgName]];
38 }
39 if (title != nil) {
40 [aCAV.titleLabel setText:title];
41 }
42
43
44 return aCAV;
45 }
46
47
48
49 -(void)show{
50 //首先找到唯一控制这个viewcontroller的appdelegate
51 AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
52 //找到默认控制的窗口
53 [delegate.window addSubview:self];
54
55 }
56
57
58 -(void)dismiss{
59 [self removeFromSuperview];
60 }
61
62
63
64 - (IBAction)sureBTNdidClicked:(id)sender {
65 //先让提示框消失
66 [self dismiss];
67 //执行一下block
68 self.sureblock();
69 }
70
71
72
73 - (IBAction)cancelBTNdidClicked:(id)sender {
74 //先让提示框消失
75 [self dismiss];
76 //执行一下block
77 self.cancelblock();
78
79 }
80
81 -(void)setSureBtnWithTitle:(NSString *)title andComlished:(SureBtnBlock)sureblock{
82 //这里判断一下外部是否传title值
83 if (title != nil) {
84 [self.sureBtn setTitle:title forState:UIControlStateNormal];
85 }
86 //这里发现要用一个属性变量来保存住外部传过来的sureblock
87 self.sureblock = sureblock;
88 }
89
90 -(void)setCancelBtnWithTitle:(NSString *)title andComlished:(CancelBtnBlock)cancelblock{
91 if (title != nil) {
92 [self.cancelBtn setTitle:title forState:UIControlStateNormal];
93 }
94
95 self.cancelblock = cancelblock;
96 }
97
98
99
100 @end
 1 //
2 // ViewController.m
3 // 0310--自定义框架
4 //
5 // Created by MyMac on 2019/3/12.
6 // Copyright 2019年 MyMac. All rights reserved.
7 //
8
9 #import "ViewController.h"
10 #import "CustomAlertView.h"
11 @interface ViewController ()
12
13 @end
14
15 @implementation ViewController
16
17 - (void)viewDidLoad {
18 [super viewDidLoad];
19 // Do any additional setup after loading the view, typically from a nib.
20 UIImageView *imgview = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"tree"]];
21 imgview.frame = self.view.bounds;
22 [self.view addSubview:imgview];
23 }
24
25
26
27
28 - (void)didReceiveMemoryWarning {
29 [super didReceiveMemoryWarning];
30 // Dispose of any resources that can be recreated.
31 }
32
33 -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
34 CustomAlertView *alertView = [CustomAlertView alertViewWithImagename:@"ok" andTitle:@"吃了吗" andSytle:kCustomAlertViewSytleUpAndDown];
35
36 [alertView show];
37 [alertView setSureBtnWithTitle:@"吃了" andComlished:^{
38 //这里可以做一些你想点击完确认按钮后做的事
39 //......
40 NSLog(@"确认键被点击了");
41
42 }];
43 [alertView setCancelBtnWithTitle:@"没吃" andComlished:^{
44 NSLog(@"取消键被点击了");
45 }];
46 }
47
48
49
50 @end

自定义控件CustomAlertView的更多相关文章

  1. android自定义控件一站式入门

    自定义控件 Android系统提供了一系列UI相关的类来帮助我们构造app的界面,以及完成交互的处理. 一般的,所有可以在窗口中被展示的UI对象类型,最终都是继承自View的类,这包括展示最终内容的非 ...

  2. ASP.NET MVC学习之母版页和自定义控件的使用

    一.母板页_Layout.cshtml类似于传统WebForm中的.master文件,起到页面整体框架重用的目地1.母板页代码预览 <!DOCTYPE html> <html> ...

  3. C# 自定义控件VS用户控件

    1 自定义控件与用户控件区别 WinForm中, 用户控件(User Control):继承自 UserControl,主要用于开发 Container 控件,Container控件可以添加其他Con ...

  4. 自定义控件之 圆形 / 圆角 ImageView

    一.问题在哪里? 问题来源于app开发中一个很常见的场景——用户头像要展示成圆的:       二.怎么搞? 机智的我,第一想法就是,切一张中间圆形透明.四周与底色相同.尺寸与头像相同的蒙板图片,盖在 ...

  5. 如何开发FineReport的自定义控件?

    FineReport作为插件化开发的报表软件,有些特殊需求的功能需要自己开发,开发的插件包帆软官方有提提供,可以去帆软论坛上找,本文将主要介绍如何开发一个自定义控件,这里讲讲方法论. 第一步:实例化一 ...

  6. WPF自定义控件第二 - 转盘按钮控件

    继之前那个控件,又做了一个原理差不多的控件.这个控件主要模仿百度贴吧WP版帖子浏览界面左下角那个弹出的按钮盘.希望对大家有帮助. 这个控件和之前的也差不多,为了不让大家白看,文章最后发干货. 由于这个 ...

  7. 【Win 10应用开发】AdaptiveTrigger在自定义控件中是可以触发的

    前些天,看到有网友给我留言,说AdaptiveTrigger在自定义控件(模板化控件)中不能触发.因为当时我正在写其他的代码,就没有去做实验来验证,于是我就给这位网友提了使用GotoVisualSta ...

  8. WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...

  9. Android自定义控件之自定义ViewGroup实现标签云

    前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...

随机推荐

  1. (四)FastDFS 高可用集群架构学习---后期运维--基础知识及常用命令

    1.fastdfs 七种状态 FDFS_STORAGE_STATUS:INIT :初始化,尚未得到同步已有数据的源服务器 FDFS_STORAGE_STATUS:WAIT_SYNC :等待同步,已得到 ...

  2. 使用jax加速Hamming Distance的计算

    技术背景 一般认为Jax是谷歌为了取代TensorFlow而推出的一款全新的端到端可微的框架,但是Jax同时也集成了绝大部分的numpy函数,这就使得我们可以更加简便的从numpy的计算习惯中切换到G ...

  3. robot_framewok自动化测试--(2)创建第一个项目

    创建第一个robot_framewok项目 通过 RIDE 去学习和使用 Robot Framework 框架,对于初学者来说大大的降低了学习难度.所以后面对 Robot Framework 框架都将 ...

  4. ES6-字符串-模板字符串(复习+学习)

    昨天学习了字符串对象和字符串的表示,就是利用utf-8等不同的编码方式,还有许多的对象方法,都是处理字符串的方法,挺方便的,今天我学习了一下字符串模板,这里记录i一下学习的笔记,当然,今天学习了部分内 ...

  5. 数据库炸了----我就重启了一下啊(Communications link failure)

    重启数据库后,数据库大部分时间连不上了:连续请求不会报错,请求间隔时间稍微长一点就会报错报错如图: com.mysql.cj.jdbc.exceptions.CommunicationsExcepti ...

  6. Modelsim仿真新手入门最详细教程

    2021年11月15日 00 安装包/版本 我是提前在网上下好的(但这一点也给我的实验造成了"麻烦"),用的是Modelsim SE-64 2020.4版本的,学校实验室的似乎不同 ...

  7. 大爽Python入门教程 2-1 认识容器

    大爽Python入门公开课教案 点击查看教程总目录 1 什么是容器 先思考这样一个场景: 有五个学生,姓名分别为: Alan, Bruce, Carlos, David, Emma. 需要给他们都打一 ...

  8. python中整除后结果也是小数

    有人这么回答,这显然不对 先看个例子: '//'明明是整除,为什么结果不是整数,而会出现小数? 首先,关于除法有三种概念:传统除法.精确除法和地板除 #1.传统除法:整数相除结果是整数,浮点数相除结果 ...

  9. Java包装类,以及Integer与int之间的比较

    一.Java的基本类型 Java语言中提供了八种基本类型,包括六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. 整数型,包括byte.short.int.long,默认初始值是0 ...

  10. [luogu5616]恶魔之树

    记录$lcm$的质因子状态(包括大于$\sqrt 300$的质因子),设$f[s]$表示质因子状态为$s$的$lcm$之和,转移枚举当前的数$k$,转移到$lcm(s,k)$即可,时间复杂度为$o(n ...