iOS 控件封装iOS新手学习其他一丢丢

iOS开发 | 封装自定义弹窗

2017-04-08  本文已影响3537人  Lol刀妹
智妍

写在前面

弹窗是app中常见控件之一,一般由于项目需求,我们很少能直接使用系统提供的弹窗,这个时候就需要我们根据产品需求封装自定义弹窗了。这两天正好封装了一个弹窗,分享出来(主要是思路),希望新手少走点弯路,当然更希望高手能提出一些实在的建议哈哈😄。总之,只要思路清晰点,封装一般的弹窗还是没有问题的😎。

先看看UI设计图

UI设计图

其中,红色文本和灰色方框里的文本是后台返回的。


我做出的效果

demo中的效果.gif 项目中的效果,后台未返回说明文字的情况.gif

思路

- (void)showAlert{
    UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"标题" message:@"内容" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
    [alertView show];
}

UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"标题" message:@"内容" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];

这句是调用UIAlertView的构造方法初始化一个UIAlertView对象。

[alertView show];

这句是调用这个UIAlertView对象的show方法,将弹窗show出来。

开始封装

一. 弹窗命名

系统的叫UIAlertView,那么我这个根据弹窗的功能就给它取名DeclareAbnormalAlertView

二. 构造方法的命名

系统的叫:

- (instancetype)initWithTitle:(nullable NSString *)title message:(nullable NSString *)message delegate:(nullable id /*<UIAlertViewDelegate>*/)delegate cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitles:(nullable NSString 
*)otherButtonTitles, ...`。

我的这个弹窗,因为有且只有两个按钮(向PM确认),所以命名为:

- (instancetype)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate leftButtonTitle:(NSString *)leftButtonTitle rightButtonTitle:(NSString *)rightButtonTitle;

三. 弹出这个弹窗的方法命名

/** show出这个弹窗 */
- (void)show;

当然还是show😄

四. 构造方法的实现

弹窗,说白了就是一个覆盖在屏幕顶层的半透明view

  1. 弹窗的最底部是覆盖全屏的半透明view
  2. 根据UI设计图,添加subViews到半透明view上
  3. 这里就不贴代码了,文末有demo😅

五. show方法的实现

show其实就是将弹窗放在最顶层,如何将view放在最顶层,我知道的有这几种方式:

  1. 直接在当前视图控制器上放view(简直6翻了)
  2. present到一个新的半透明视图控制器(想想UIAlertViewController,如果要使用这种弹窗的话,自定义的弹窗就是继承自UIViewController而不是UIView了)
  3. 使用一个windowLevel更高的UIWindowUIAlertView就是这种)
  4. 放在keyWindow上(使用这种方式有隐患,点击查看详情
  5. 放在[UIApplication sharedApplication] delegate] window]上(我起初是放在keyWindow上的,后面改成了这种)

六. 代理方法的命名:

系统的代理方法叫:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;

所以我写的代理方法是:

- (void)declareAbnormalAlertView:(DeclareAbnormalAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;

注意事项:

  1. 弹窗里有UITextView,注意不要让键盘挡住弹窗。处理方式:监听键盘显示和隐藏并对弹窗做出相应调整:
// 接收键盘显示隐藏的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHidden:) name:UIKeyboardWillHideNotification object:nil];
/**
 *  键盘将要显示
 *
 *  @param notification 通知
 */
-(void)keyboardWillShow:(NSNotification *)notification
{
    // 获取到了键盘frame
    CGRect frame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat keyboardHeight = frame.size.height;
    
    self.contentView.maxY = SCREEN_HEIGHT - keyboardHeight - 10;
}
/**
 *  键盘将要隐藏
 *
 *  @param notification 通知
 */
-(void)keyboardWillHidden:(NSNotification *)notification
{
    // 弹窗回到屏幕正中
    self.contentView.centerY = SCREEN_HEIGHT / 2;
}

使用封装好的弹窗

DeclareAbnormalAlertView *alertView = [[DeclareAbnormalAlertView alloc]
                                          initWithTitle:@"填写异常信息" 
                                          message:responseDict[@"data"][@"apply_exception_overtime"] 
                                          delegate:self 
                                          leftButtonTitle:@"申报异常" 
                                          rightButtonTitle:@"取消"];

[alertView show];

代理方法:

/** 申报异常弹窗的代理方法 */
- (void)declareAbnormalAlertView:(DeclareAbnormalAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (buttonIndex == AlertButtonLeft) { // 申报异常按钮点击
    }
}

是不是感觉就像在用系统的弹窗?恩,要的就是这种感觉。为什么要努力向系统弹窗靠近?理由有三:

  1. 每个人的编码风格都不同,但有一点毋庸置疑,那就是,每一个开发者对这些常用系统方法肯定都很熟悉,如果你的方法和系统方法类似,相信其他人维护时一定会有似曾相识的感觉。
  2. 我们写代码应该尽量按照官方推荐的编码规范来写,而这些系统方法,就是最好的例子。
  3. 只有这样严格要求自己,养成良好的编码习惯,才算得上一个合格的程序员。

详情请查看demo

点击查看demo

上一篇下一篇

猜你喜欢

热点阅读