1. 程式人生 > >iOS 你需要的彈窗大全

iOS 你需要的彈窗大全

在我們的實際開發專案中,彈窗是必不可少的,很多時候我們用的是系統的AlertViewController,但是實際情況中,並不能滿足我們的開發需求,這個時候我們需要的就是自定義自己的彈窗效果。接下來我會寫一些自己的所封裝的彈窗效果。包括代理delegate回撥,block 回撥,xib新建view來建立我們需要的彈窗效果。

官方思路

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];

因為在程式碼量風格上,我還是比較喜歡老版本的彈窗,畢竟程式碼上啊,一句話呼叫美滋滋。所以接下來我們封裝也是模仿官方開始.....

delegate

我們可以看到在蘋果官方中,我們需要通過識別使用者點選某個按鈕來確定需要進一步的操作事件,這個時候是通過代理來實現的。代理的話,我們在熟悉不過了。

  1. 首先申明協議
#pragma mark - 協議
@class HLAlertView;
@protocol HLAlertViewDelegate<NSObject>
- (void)alertViewDidClickButtonWithIndex:(NSInteger)index;
@end
  1. 在viewController中遵循代理,設定代理 , 實現方法即可
<HLAlertViewDelegate>
self.delegate = self;

#pragma mark --- HLAlertViewDelegate
-(void)alertViewDidClickButtonWithIndex:(NSInteger)index{
    if (index == AlertSureButtonClick) {
        [self alertSureButtonClick];
    }else{
        [self alertCauseButtonClick];
    }
}
  1. 接下來就是實現我們封裝類的.h檔案方法申明,以及.m的實現方法
//.h 檔案
#import <UIKit/UIKit.h>

typedef enum : NSUInteger {
    AlertCauseButtonClick = 0,
    AlertSureButtonClick
} AlertButtonClickIndex;

#pragma mark - 協議
@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()

/** 彈窗主內容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;
    }];
    
    //------- 彈窗主內容 -------//
    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彈窗

先看一下封裝之後我們的呼叫方式吧:

HLAlertViewBlock * alertView = [[HLAlertViewBlock alloc] initWithTittle:@"提示" message:@"通過Block彈窗回撥的彈窗" block:^(NSInteger index) {
        if (index == AlertSureButtonClick) {
            [self alertSureButtonClick];
        }else{
            [self alertCauseButtonClick];
        }
    }];
    [alertView show];

相比代理的方式的話,我們還行喜歡這種block回撥的,簡大氣接地氣啊。當然在我們需要處理邏輯多的時候,還是代理會比較好一點,具體環境下具體使用。 封裝成block的好處就是在我們構造方法的時候就可以實現我們將來的點選方法,所以在自定義彈窗類的.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()

/** 彈窗主內容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的封裝彈窗

圖片.png

好處就是不用寫介面程式碼了。

殊途同歸

還有一種實現彈窗效果的方法,不通過新建view而是Controller來實現的,就是新建一個透明的控制器。程式碼如下

    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];

作者:MrBMask 連結:https://www.jianshu.com/p/817c8e71f1f8 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。