zoukankan      html  css  js  c++  java
  • 自定义控件CustomAlertView

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

    效果如下:

     

     可行性分析:

    由于系统自带的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
  • 相关阅读:
    Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解
    40个Java多线程问题总结
    Windows10实用技巧-固定快捷方式到磁贴菜单方式
    wordpress初始化安装
    xshell输入奇怪,空格间距变大
    Python2和Python3共存安装
    搭建nginx反向代理用做内网域名转发
    下载网页视频音频方法(djyeye为例)
    Dell 戴尔预装Windows8改成Windows7
    Nginx基本功能极速入门
  • 原文地址:https://www.cnblogs.com/apprendre-10-28/p/10507794.html
Copyright © 2011-2022 走看看