在我們的實際開發(fā)項目中黍匾,彈窗是必不可少的栏渺,很多時候我們用的是系統(tǒng)的AlertViewController,但是實際情況中锐涯,并不能滿足我們的開發(fā)需求磕诊,這個時候我們需要的就是自定義自己的彈窗效果。接下來我會寫一些自己的所封裝的彈窗效果纹腌。包括代理delegate回調(diào)霎终,block 回調(diào),xib新建view來創(chuàng)建我們需要的彈窗效果升薯。
官方思路
1.在我們自己動手之前一定要先看看官方是怎么封裝的莱褒,這樣我們寫出來的代碼才接近蘋果語言,看起來高大上涎劈。好的代碼一定是見名知意的广凸,別人一看這個方法就知道大概我們通過這個方法可以得到什么樣的效果。
// ios8.0 之后
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"確定");
}];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
// ios8.0 之前
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"Tittle" message:@"This is message" delegate:self
cancelButtonTitle:@"cancel" otherButtonTitles:nil, nil];
[alertView show];
因為在代碼量風(fēng)格上责语,我還是比較喜歡老版本的彈窗炮障,畢竟代碼上啊目派,一句話調(diào)用美滋滋坤候。所以接下來我們封裝也是模仿官方開始.....
delegate
我們可以看到在蘋果官方中,我們需要通過識別用戶點擊某個按鈕來確定需要進一步的操作事件企蹭,這個時候是通過代理來實現(xiàn)的白筹。代理的話智末,我們在熟悉不過了。
- 首先申明協(xié)議
#pragma mark - 協(xié)議
@class HLAlertView;
@protocol HLAlertViewDelegate<NSObject>
- (void)alertViewDidClickButtonWithIndex:(NSInteger)index;
@end
- 在viewController中遵循代理徒河,設(shè)置代理 系馆, 實現(xiàn)方法即可
<HLAlertViewDelegate>
self.delegate = self;
#pragma mark --- HLAlertViewDelegate
-(void)alertViewDidClickButtonWithIndex:(NSInteger)index{
if (index == AlertSureButtonClick) {
[self alertSureButtonClick];
}else{
[self alertCauseButtonClick];
}
}
- 接下來就是實現(xiàn)我們封裝類的.h文件方法申明,以及.m的實現(xiàn)方法
//.h 文件
#import <UIKit/UIKit.h>
typedef enum : NSUInteger {
AlertCauseButtonClick = 0,
AlertSureButtonClick
} AlertButtonClickIndex;
#pragma mark - 協(xié)議
@class HLAlertView;
@protocol HLAlertViewDelegate<NSObject>
- (void)alertViewDidClickButtonWithIndex:(NSInteger)index;
@end
@interface HLAlertView : UIView
@property(nonatomic, weak) id <HLAlertViewDelegate> delegate;
- (instancetype)initWithTittle:(NSString *)tittle message:(NSString *)message sureButton:(NSString *)sureBtn;
- (void)show;
@end
@interface HLAlertView()
/** 彈窗主內(nèi)容view */
@property (nonatomic,strong) UIView *contentView;
/** 彈窗標題 */
@property (nonatomic,copy) NSString *title;
/** message */
@property (nonatomic,copy) NSString *message;
/** 確認按鈕 */
@property (nonatomic,copy) UIButton *sureButton;
@end
@implementation HLAlertView
- (instancetype)initWithTittle:(NSString *)tittle message:(NSString *)message sureButton:(NSString *)sureBtn{
if (self = [super init]) {
self.title = tittle;
self.message = message;
[self sutUpView];
}
return self;
}
- (void)sutUpView{
self.frame = [UIScreen mainScreen].bounds;
self.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.85];
[UIView animateWithDuration:0.5 animations:^{
self.alpha = 1;
}];
//------- 彈窗主內(nèi)容 -------//
self.contentView = [[UIView alloc]init];
self.contentView.frame = CGRectMake(0, 0, SCREEN_WIDTH - 80, 150);
self.contentView.center = self.center;
self.contentView.backgroundColor = [UIColor whiteColor];
self.contentView.layer.cornerRadius = 6;
[self addSubview:self.contentView];
// 標題
UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, self.contentView.width, 22)];
titleLabel.font = [UIFont boldSystemFontOfSize:20];
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.text = self.title;
[self.contentView addSubview:titleLabel];
// message
UILabel *messageLable = [[UILabel alloc]initWithFrame:CGRectMake(0, 50, self.contentView.width, 22)];
messageLable.font = [UIFont boldSystemFontOfSize:17];
messageLable.textAlignment = NSTextAlignmentCenter;
messageLable.text = self.message;
[self.contentView addSubview:messageLable];
// 取消按鈕
UIButton * causeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
causeBtn.frame = CGRectMake(0, self.contentView.height - 40, self.contentView.width/2, 40);
causeBtn.backgroundColor = [UIColor grayColor];
[causeBtn setTitle:@"取消" forState:UIControlStateNormal];
[causeBtn addTarget:self action:@selector(causeBtn:) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:causeBtn];
// 確認按鈕
UIButton * sureButton = [UIButton buttonWithType:UIButtonTypeCustom];
sureButton.frame = CGRectMake(causeBtn.width, causeBtn.y, causeBtn.width, 40);
sureButton.backgroundColor = [UIColor redColor];
[sureButton setTitle:@"確定" forState:UIControlStateNormal];
[sureButton addTarget:self action:@selector(processSure:) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:sureButton];
}
- (void)show{
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
[keyWindow addSubview:self];
}
- (void)processSure:(UIButton *)sender{
if ([self.delegate respondsToSelector:@selector(alertViewDidClickButtonWithIndex:)]) {
[self.delegate alertViewDidClickButtonWithIndex:AlertSureButtonClick];
}
[self dismiss];
}
- (void)causeBtn:(UIButton *)sender{
if ([self.delegate respondsToSelector:@selector(alertViewDidClickButtonWithIndex:)]) {
[self.delegate alertViewDidClickButtonWithIndex:AlertCauseButtonClick];
}
[self dismiss];
}
#pragma mark - 移除此彈窗
/** 移除此彈窗 */
- (void)dismiss{
[self removeFromSuperview];
}
通過代理的方式我們就完成了我們自己頁面的封裝了顽照。
block彈窗
先看一下封裝之后我們的調(diào)用方式吧:
HLAlertViewBlock * alertView = [[HLAlertViewBlock alloc] initWithTittle:@"提示" message:@"通過Block彈窗回調(diào)的彈窗" block:^(NSInteger index) {
if (index == AlertSureButtonClick) {
[self alertSureButtonClick];
}else{
[self alertCauseButtonClick];
}
}];
[alertView show];
相比代理的方式的話由蘑,我們還行喜歡這種block回調(diào)的,簡大氣接地氣啊代兵。當然在我們需要處理邏輯多的時候尼酿,還是代理會比較好一點美澳,具體環(huán)境下具體使用笨农。
封裝成block的好處就是在我們構(gòu)造方法的時候就可以實現(xiàn)我們將來的點擊方法,所以在自定義彈窗類的.h文件中斯碌,我們要申明block屬性思币。代碼
//.h
@interface HLAlertViewBlock : UIView
@property(nonatomic, copy) void (^buttonBlock) (NSInteger index);
- (instancetype)initWithTittle:(NSString *)tittle message:(NSString *)message block:(void (^) (NSInteger index))block;
- (void)show;
@end
//.m
@interface HLAlertViewBlock()
/** 彈窗主內(nèi)容view */
@property (nonatomic,strong) UIView *contentView;
/** 彈窗標題 */
@property (nonatomic,copy) NSString *title;
/** message */
@property (nonatomic,copy) NSString *message;
/** 確認按鈕 */
@property (nonatomic,copy) UIButton *sureButton;
@end
@implementation HLAlertViewBlock
- (instancetype)initWithTittle:(NSString *)tittle message:(NSString *)message block:(void (^)(NSInteger))block{
if (self = [super init]) {
self.title = tittle;
self.message = message;
self.buttonBlock = block;
[self sutUpView];
}
return self;
}
到此為止鹿响,我們的block彈窗申明方法也搞定了。
xib的封裝彈窗
好處就是不用寫界面代碼了谷饿。
殊途同歸
還有一種實現(xiàn)彈窗效果的方法惶我,不通過新建view而是Controller來實現(xiàn)的,就是新建一個透明的控制器博投。代碼如下
PopViewController * popVC = [[PopViewController alloc] init];
UIColor * color = [UIColor blackColor];
popVC.view.backgroundColor = [color colorWithAlphaComponent:0.85];
popVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:popVC animated:NO completion:nil];
更加簡單指孤,邏輯也更加好處理一些。
最后附上demo地址:gibHub地址:https://github.com/MrBMask