使用runtime 封装一个自定义Alert

在开发中,系统自带的UIAlert 往往不能满足需求。这时就需要来自定义一个alert了。为了方便使用可以对UIViewController添加类目,然后再用runtime添加属性来自定义alert。

在编写之前我们先来看一下UIAlertControllerUIAlertController是继承自UIViewController,为UIViewController的子类,也是一个视图控制器,并且在调用的时候是使用presentViewController来模态调用的,但是调用完成后的效果是显示在调用viewcontroller的上面的:

使用runtime 封装一个自定义Alert_第1张图片
示意图

所以可以猜测UIAlertController是被弹出模态后,修改视图控制器的背景的透明度 就可以达到这样的效果。再仔细看一下 弹出模态视图的时候,是会把导航栏一起遮盖的。
而要利用UIViewController添加类目达到这样的效果,首先想到的是在类目中的弹出方法中,添加一个window,覆盖在UIViewController上。

开始封装自定义Alert

首先新建一个UIViewController的类目,其中定义好需要用到的属性、方法和回调的block

typedef void (^CancelAlert)();
typedef void (^CertainAlert)();

@property (nonatomic, assign) CancelAlert cancelAlert;
@property (nonatomic, assign) CertainAlert certainAlert;

- (void)showMyAlert:(NSString *)title withCancelMsg:(NSString *)cancelMsg withCancelBlock:(CancelAlert)cancelAlert withCertainMsg:(NSString *)certainMsg withCertainBlock:(CertainAlert)certainAlert;

然后再在.m中使用runtime修饰属性

static const void *cancelAlertKey = &cancelAlertKey;
static const void *certainAlertKey = &certainAlertKey;
static const void *certainTextFieldKey = &certainTextFieldKey;

- (CancelAlert)cancelAlert {
    return objc_getAssociatedObject(self, cancelAlertKey);
}
- (void)setCancelAlert:(CancelAlert)cancelAlert {
    objc_setAssociatedObject(self, cancelAlertKey, cancelAlert, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (CertainAlert)certainAlert {
    return objc_getAssociatedObject(self, certainAlertKey);
}
- (void)setCertainAlert:(CertainAlert)certainAlert {
    objc_setAssociatedObject(self, certainAlertKey, certainAlert, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (CertainTextField)certainTextField {
    return objc_getAssociatedObject(self, certainTextFieldKey);
}
- (void)setCertainTextField:(CertainTextField)certainTextField {
    objc_setAssociatedObject(self, certainTextFieldKey, certainTextField, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

然后实现显示alert的方法

- (void)showTextFieldAlert:(NSString *)title withPlaceholder:(NSString *)placeholder withCancelMsg:(NSString *)cancelMsg withCancelBlock:(CancelAlert)cancelAlert withCertainMsg:(NSString *)certainMsg withCertainBlock:(CertainTextField)certainTextField {
    self.cancelAlert = cancelAlert;
    self.certainTextField = certainTextField;
    
    [self.view endEditing:YES];
    
    [self _createView:MyAlertTextField withPlaceholder:placeholder withTitle:title withCancelMsg:cancelMsg withCertainMsg:certainMsg];
}
#pragma mark 创建视图
- (void)_createView:(MyAlertType)myAlertType withPlaceholder:(NSString *)placeholder withTitle:(NSString *)title withCancelMsg:(NSString *)cancelMsg withCertainMsg:(NSString *)certainMsg {
    // 创建视图
    UIView *bgView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    bgView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:0.5];
    bgView.tag = 4001;
    [UIApplication.sharedApplication.delegate.window addSubview:bgView];
    .........
}

其中的具体实现可以参照 demo

下面放两张效果图:

使用runtime 封装一个自定义Alert_第2张图片
alert.png
使用runtime 封装一个自定义Alert_第3张图片
field.png

最后 WLAlert 已经封装好可以直接使用pod 集成,使用

$pod search WLAlert

就可以搜索到了。
使用的时候直接导入头文件#import 就行了。

你可能感兴趣的:(使用runtime 封装一个自定义Alert)