〇、目地
为什么会选择设计BBAlertViewController
组件呢?主要有两个重要的原因:一、就目前项目而言,目前项目中维护了20多个不同种类的Alert
弹框,维护起来确实耗时耗力,结果不尽人意;二、新项目开发过程中避免第一种情况再次发生,而又能多功能复用的控件。基于这两个重要原因,所以花了一点时间设计自定义的BBViewController
组件。
一、功能介绍
自定义BBAlertViewController
组件主要实现在项目中并存多个自定义的情况,可以删除更多关于弹框的冗余代码,实现更高效、更高自主的弹框方式,主要功能如下:
- 1、经典的
BBAlertController
与iOS Native
显示模式无异。结合BBAlertViewController
可以更好衔接原生的开发,一旦项目中AlertViewController
样式变动,只需要把对应的中间工具类一变,即可以实现需求,完美而又快捷。 - 2、可以根据项目主色调整
BBAlertViewController
中的任意一个色值。可以根据组件提供的属性实现各种UI
的展示,不需要去处理一行适应的代码,让开发变得更简单。 - 3、高度自定义
BBAlertViewController
显示样式。可以根据自已的UI
界面,呈现出各种不一样的AlertViewController
,轻松应付UI
设计,如:弹框中需在加入背景图片、每个按钮都有一个不同的图标、需要在AlertViewController
里面实现文字与图片的布局等等。 - 4、实现插桩模式的自定义
BBAlertViewController
弹框。可以通过外部代码控制我们AlertViewController
中的显示,可以通过点击AlertViewController
中的按钮获取自已框里同的值,可以在外部直接通过Masonry
布局,让开发者神往的小工具。
二、设计思路
自定义BBAlertViewController
实现采用的语言是Objective-C
,设计思路参考了iOS
中的WKWebView
设计方案,采用单独的配置文件实现所有的属性与功能配置。界面展示采用Native
的UIAlertController
,以ViewController
为宿主,减少内存实例化过多的问题。
首先、BBAlertViewController的弹框模式
+ (instancetype)alertViewControllerWithTitle:(NSString *)title withMessage:(NSString *)message withConfiguration:(nonnull BBAlertConfiguration *)alertConfiguration {
BBAlertViewController *instance = [[self alloc] init];
// 因为现在加入自定义东西,所以有的时候不能处理
// if (title.length < 1 && message.length < 1) {
// NSAssert(NO, @"Title和Message必须有一个有值");
// }
//这个必须放在最前面,不然不能正常执行到
instance.alertConfiguration = alertConfiguration;
instance.titleString = title;
instance.messageString = message;
//设置view.backgroundColor就已经开始执行viewDidLoad方法
instance.view.backgroundColor = [UIColor colorWithHex:0x333333 alpha:0.5f];
instance.modalPresentationStyle = UIModalPresentationOverCurrentContext;
return instance;
}
其次、整个BBAlertViewController
的所有设置的属性统一在BBAlertConfiguration
类中,有两个好处:一、统一管理属性;二、属性与ViewController
分开(实现原理如NSURLSession
/WKWebView
一致)。
三、项目使用
1、直接从GITHUB中下载代码到当前项目中,git地址:https://gitee.com/MiBao12/BBAlertViewController
2、封装专门的弹框类库,如:
#import "BBAlertViewTools.h"
#import "BBAlertViewController.h"
#import "BBAlertConfiguration.h"
#import "BBAlertAction.h"
@interface BBAlertViewTools ()
@end
@implementation BBAlertViewTools
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withConfirmTitle:(NSString *)confirmTitle {
[self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:@"" withConfirmTitle:confirmTitle withCancelTitle:@"" withEventBlock:^(NSInteger index) {
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewConroller:(UIViewController *)viewConroller withConfirmTitle:(NSString *)confirmTitle {
[self alertViewWithAlertTitle:alertTitle withViewConroller:viewConroller withMessage:@"" withConfirmTitle:confirmTitle withCancelTitle:@"" withEventBlock:^(NSInteger index) {
}];
}
+ (void)alertViewDefaultWithMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle {
[self alertViewWithAlertTitle:@"温馨提示" withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:@"" withEventBlock:^(NSInteger index) {
}];
}
+ (void)alertViewDefaultWithMessage:(NSString *)message withViewController:(UIViewController*)viewController withConfirmTitle:(NSString *)confirmTitle {
[self alertViewWithAlertTitle:@"温馨提示" withViewConroller:viewController withMessage:message withConfirmTitle:confirmTitle withCancelTitle:@"" withEventBlock:^(NSInteger index) {
}];
}
+ (void)alertViewWithMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle {
[self alertViewWithAlertTitle:@"" withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
}];
}
+ (void)alertViewWithMessage:(NSString *)message withViewController:(UIViewController*)viewController withConfirmTitle:(NSString *)confirmTitle {
[self alertViewWithAlertTitle:@"" withViewConroller:viewController withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle {
[self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewController:(UIViewController*)viewController withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle {
[self alertViewWithAlertTitle:alertTitle withViewConroller:viewController withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(void))eventBlock {
[self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:message withConfirmTitle:nil withCancelTitle:cancelTitle withEventBlock:^(NSInteger index) {
if (eventBlock) {
eventBlock();
}
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewController:(UIViewController*)viewController withMessage:(NSString *)message withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(void))eventBlock {
[self alertViewWithAlertTitle:alertTitle withViewConroller:viewController withMessage:message withConfirmTitle:nil withCancelTitle:cancelTitle withEventBlock:^(NSInteger index) {
if (eventBlock) {
eventBlock();
}
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withEventBlock:(void(^)(void))eventBlock {
[self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
if (eventBlock) {
eventBlock();
}
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewConroller:(UIViewController *)viewController withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withEventBlock:(void(^)(void))eventBlock {
[self alertViewWithAlertTitle:alertTitle withViewConroller:viewController withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
if (eventBlock) {
eventBlock();
}
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewConroller:(UIViewController *)viewController withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
BBAlertConfiguration *defaultConfiguration = [BBAlertConfiguration defaultAlertViewConfiguration];
defaultConfiguration.verticalHidden = YES;
defaultConfiguration.acrossHidden = YES;
defaultConfiguration.actionDirection = BBActionDirectionDefault;
defaultConfiguration.typeDefaultBackgroundColor = BB_MainColor;
defaultConfiguration.actionEdgeInsets = UIEdgeInsetsMake(10,20, 30, 20);
defaultConfiguration.typeCancelBackgroundColor = BB_HexColor(0xffffff);
defaultConfiguration.cancelBorderColor = BB_MainColor;
defaultConfiguration.cancelBorderWidth = BB_Relative(1.f);
defaultConfiguration.defaultBorderColor = BB_MainColor;
defaultConfiguration.defaultBorderWidth = BB_Relative(1.f);
defaultConfiguration.actionHeight = 40.f;
defaultConfiguration.actionCornerRadius = 8.f;
BBAlertViewController *alertViewController = [BBAlertViewController alertViewControllerWithTitle:alertTitle withMessage:message withConfiguration:defaultConfiguration];
BBAlertAction *confirmAlertAction = [BBAlertAction alertActionWithActionTitle:confirmTitle withActionType:BBAlertActionTypeDefault withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
if (eventBlock) {
eventBlock(1);
}
}];
BBAlertAction *cancelAlertAction = [BBAlertAction alertActionWithActionTitle:cancelTitle withActionType:BBAlertActionTypeCancel withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
if (eventBlock) {
eventBlock(0);
}
}];
if (confirmTitle != nil && confirmTitle.length > 0) {
[alertViewController addAction:confirmAlertAction];
}
if (cancelTitle != nil && cancelTitle.length > 0) {
[alertViewController addAction:cancelAlertAction];
}
UIViewController *tempViewController = viewController;
if (viewController == nil) {
tempViewController = [BBUICommonTools findCurrentShowingViewController];
if (tempViewController.tabBarController != nil) {
tempViewController = tempViewController.tabBarController;
}
}
[tempViewController presentViewController:alertViewController animated:NO completion:^{
}];
}
+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
[self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:cancelTitle withEventBlock:^(NSInteger index) {
if (eventBlock) {
eventBlock(index);
}
}];
}
+ (void)alertViewVerticalWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
BBAlertConfiguration *defaultConfiguration = [BBAlertConfiguration defaultAlertViewConfiguration];
defaultConfiguration.verticalHidden = YES;
defaultConfiguration.acrossHidden = YES;
defaultConfiguration.actionDirection = BBActionDirectionVertical;
defaultConfiguration.actionEdgeInsets = UIEdgeInsetsMake(10,20, 30, 20);
defaultConfiguration.typeCancelBackgroundColor = BB_MainColor;
defaultConfiguration.cancelBorderColor = BB_MainColor;
defaultConfiguration.cancelBorderWidth = BB_Relative(1.f);
defaultConfiguration.typeCancelColor = [UIColor whiteColor];
defaultConfiguration.defaultBorderColor = BB_MainColor;
defaultConfiguration.defaultBorderWidth = BB_Relative(1.f);
defaultConfiguration.typeDefaultBackgroundColor = [UIColor whiteColor];
defaultConfiguration.typeDefaultColor = BB_MainColor;
defaultConfiguration.actionHeight = 40.f;
defaultConfiguration.actionCornerRadius = 8.f;
BBAlertViewController *alertViewController = [BBAlertViewController alertViewControllerWithTitle:alertTitle withMessage:message withConfiguration:defaultConfiguration];
BBAlertAction *confirmAlertAction = [BBAlertAction alertActionWithActionTitle:confirmTitle withActionType:BBAlertActionTypeCancel withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
if (eventBlock) {
eventBlock(1);
}
}];
BBAlertAction *cancelAlertAction = [BBAlertAction alertActionWithActionTitle:cancelTitle withActionType:BBAlertActionTypeDefault withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
if (eventBlock) {
eventBlock(0);
}
}];
if (confirmTitle != nil && confirmTitle.length > 0) {
[alertViewController addAction:confirmAlertAction];
}
if (cancelTitle != nil && cancelTitle.length > 0) {
[alertViewController addAction:cancelAlertAction];
}
UIViewController *tempViewController = [BBUICommonTools findCurrentShowingViewController];
if (tempViewController.tabBarController != nil) {
tempViewController = tempViewController.tabBarController;
}
[tempViewController presentViewController:alertViewController animated:NO completion:^{
}];
}
+ (void)alertViewCustomMessageViewWithAlertTitle:(NSString *)alertTitle withMessageView:(UIView *)messageView withLayerUIBlock:(void(^)(void))layerUIBlock withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
[self alertViewCustomMessageViewWithAlertTitle:alertTitle withViewController:nil withMessageView:messageView withLayerUIBlock:layerUIBlock withConfirmTitle:confirmTitle withCancelTitle:cancelTitle withEventBlock:^(NSInteger index) {
if (eventBlock) {
eventBlock(index);
}
}];
}
+ (void)alertViewCustomMessageViewWithAlertTitle:(NSString *)alertTitle withViewController:(UIViewController *)viewController withMessageView:(UIView *)messageView withLayerUIBlock:(void(^)(void))layerUIBlock withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
BBAlertConfiguration *defaultConfiguration = [BBAlertConfiguration defaultAlertViewConfiguration];
defaultConfiguration.verticalHidden = YES;
defaultConfiguration.acrossHidden = YES;
defaultConfiguration.actionDirection = BBActionDirectionDefault;
defaultConfiguration.typeDefaultBackgroundColor = BB_MainColor;
defaultConfiguration.actionEdgeInsets = UIEdgeInsetsMake(10,20, 30, 20);
defaultConfiguration.typeCancelBackgroundColor = BB_HexColor(0xffffff);
defaultConfiguration.cancelBorderColor = BB_MainColor;
defaultConfiguration.cancelBorderWidth = BB_Relative(1.f);
defaultConfiguration.defaultBorderColor = BB_MainColor;
defaultConfiguration.defaultBorderWidth = BB_Relative(1.f);
defaultConfiguration.actionHeight = 40.f;
defaultConfiguration.actionCornerRadius = 8.f;
BBAlertViewController *alertViewController = [BBAlertViewController alertViewControllerWithTitle:alertTitle withMessage:@"" withConfiguration:defaultConfiguration];
BBAlertAction *confirmAlertAction = [BBAlertAction alertActionWithActionTitle:confirmTitle withActionType:BBAlertActionTypeDefault withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
if (eventBlock) {
eventBlock(1);
}
}];
BBAlertAction *cancelAlertAction = [BBAlertAction alertActionWithActionTitle:cancelTitle withActionType:BBAlertActionTypeCancel withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
if (eventBlock) {
eventBlock(0);
}
}];
if (confirmTitle != nil && confirmTitle.length > 0) {
[alertViewController addAction:confirmAlertAction];
}
if (cancelTitle != nil && cancelTitle.length > 0) {
[alertViewController addAction:cancelAlertAction];
}
alertViewController.customContentView = messageView;
alertViewController.customLayer = layerUIBlock;
UIViewController *tempViewController = viewController;
if (tempViewController == nil) {
tempViewController = [BBUICommonTools findCurrentShowingViewController];
}
if (tempViewController.tabBarController != nil) {
tempViewController = tempViewController.tabBarController;
}
[tempViewController presentViewController:alertViewController animated:NO completion:^{
}];
}
+ (void)alertViewCustomWithAlertTitle:(NSString *)alertTitle withMessageIcon:(NSString *)messageIconName withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
UIImageView *iconImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:messageIconName]];
UILabel *titleLabel = [UILabel labelWithText:alertTitle withTextColor:BB_HexColor(0x000000) withFont:BB_RelativeBoldFont(18.f)];
UILabel *descLabel = [UILabel labelWithText:message withTextColor:BB_HexColor(0x666666) withFont:BB_RelativeFont(13.f)];
// descLabel.textAlignment = NSTextAlignmentCenter;
UIView *customView = [[UIView alloc] init];
[customView addSubview:iconImageView];
[customView addSubview:titleLabel];
[customView addSubview:descLabel];
BBAlertConfiguration *defaultConfiguration = [BBAlertConfiguration defaultAlertViewConfiguration];
defaultConfiguration.verticalHidden = YES;
defaultConfiguration.acrossHidden = YES;
defaultConfiguration.actionDirection = BBActionDirectionDefault;
defaultConfiguration.typeDefaultBackgroundColor = BB_MainColor;
defaultConfiguration.actionEdgeInsets = UIEdgeInsetsMake(10,20, 30, 20);
defaultConfiguration.typeCancelBackgroundColor = BB_HexColor(0xffffff);
defaultConfiguration.typeCancelColor = BB_HexColor(0x999999);
defaultConfiguration.cancelBorderColor = BB_HexColor(0x999999);
defaultConfiguration.cancelBorderWidth = BB_Relative(1.f);
defaultConfiguration.defaultBorderColor = BB_MainColor;
defaultConfiguration.defaultBorderWidth = BB_Relative(1.f);
defaultConfiguration.actionHeight = 40.f;
defaultConfiguration.actionCornerRadius = 8.f;
BBAlertViewController *alertViewController = [BBAlertViewController alertViewControllerWithTitle:@"" withMessage:@"" withConfiguration:defaultConfiguration];
BBAlertAction *confirmAlertAction = [BBAlertAction alertActionWithActionTitle:confirmTitle withActionType:BBAlertActionTypeDefault withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
if (eventBlock) {
eventBlock(1);
}
}];
BBAlertAction *cancelAlertAction = [BBAlertAction alertActionWithActionTitle:cancelTitle withActionType:BBAlertActionTypeCancel withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
if (eventBlock) {
eventBlock(0);
}
}];
if (confirmTitle != nil && confirmTitle.length > 0) {
[alertViewController addAction:confirmAlertAction];
}
if (cancelTitle != nil && cancelTitle.length > 0) {
[alertViewController addAction:cancelAlertAction];
}
alertViewController.customContentView = customView;
alertViewController.customLayer = ^{
[customView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.bottom.offset(0);
}];
[iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.offset(0);
make.centerX.equalTo(customView.mas_centerX).offset(0);
make.width.height.offset(BB_Relative(78));
}];
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(customView.mas_centerX).offset(0);
make.top.equalTo(iconImageView.mas_bottom).offset(BB_Relative(7));
}];
[descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(titleLabel.mas_bottom).offset(BB_Relative(15));
make.left.offset(BB_Relative(12));
make.right.offset(-BB_Relative(12));
make.bottom.offset(-BB_Relative(12));
}];
};
UIViewController *tempViewController = [BBUICommonTools findCurrentShowingViewController];
if (tempViewController.tabBarController != nil) {
tempViewController = tempViewController.tabBarController;
}
[tempViewController presentViewController:alertViewController animated:NO completion:^{
}];
}
@end
四、功能优化点
目前弹框处有一点小的问题,同时发起一个以上的弹框,只能弹出一个,后续将优化。