代码改变世界

UIAlertController Extention

2018-11-21 11:59  法子  阅读(293)  评论(0编辑  收藏  举报

GitHub地址:

https://github.com/liuyongfa/UIAlertController-Extention.git

一、Object-C

调用:

        [UIAlertController showWithTitle:@"提示" buttonTitle:@"确定" block:^{
            NSLog(@"确定");
        }];
        [UIAlertController showWithTitle:@"提示"
                                 message:nil
                      rootViewController:nil
                       cancelButtonTitle:@"取消"
                       otherButtonTitles:@[@"确定"]
                            actionBlocks:^{
                                NSLog(@"取消");
                            }, ^{
                                NSLog(@"确定");
                            }, nil];

UIAlertController+LYFExtention.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN
typedef void(^AlertBlock)(void);

@interface UIAlertController (LYFExtention)
/**
 显示UIAlertController,只有一个按钮
 @param title title
 @param buttonTitle 按钮文字
 @param block 按钮的回调
 */
+ (void)showWithTitle:(NSString *)title buttonTitle:(NSString *)buttonTitle block:(AlertBlock)block;

/**
 显示UIAlertController
 
 @param title title
 @param message message
 @param viewController 在哪个UIViewcontroller上显示,可以为nil
 @param cancelString 取消按钮文字,为nil则没有取消按钮
 @param otherTitles 其他按钮文字
 @param block 响应按钮的block,如果cancelString不为nil,则第一个为cancel按钮的,之后的block依次对应otherTitles的元素
 */
+ (void)showWithTitle:(NSString *)title message: (nullable NSString *)message rootViewController:(nullable UIViewController *)viewController cancelButtonTitle:(nullable NSString *)cancelString otherButtonTitles:(NSArray <NSString *>*)otherTitles actionBlocks:(AlertBlock)block, ...NS_REQUIRES_NIL_TERMINATION;
@end

NS_ASSUME_NONNULL_END

UIAlertController+LYFExtention.m

#import "UIAlertController+LYFExtention.h"

@implementation UIAlertController (LYFExtention)

+ (void)showWithTitle:(NSString *)title buttonTitle:(NSString *)buttonTitle block:(AlertBlock)block {
    [UIAlertController showWithTitle:title ?: @"" message:@"" rootViewController:nil cancelButtonTitle:nil otherButtonTitles:@[buttonTitle ?: @"确定"] actionBlocks:^{
        block();
    }, nil];
}

+ (void)showWithTitle:(NSString *)title message: (nullable NSString *)message rootViewController:(nullable UIViewController *)viewController cancelButtonTitle:(nullable NSString *)cancelString otherButtonTitles:(NSArray <NSString *>*)otherTitles actionBlocks:(AlertBlock)block, ... {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message ?: @"" preferredStyle:UIAlertControllerStyleAlert];
    int i = 0;
    if (cancelString) {
        [alert addAction:[UIAlertAction actionWithTitle:cancelString style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            block();
        }]];
    } else {
        if (otherTitles.count > 0) {
            [alert addAction:[UIAlertAction actionWithTitle:otherTitles[0] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                block();
            }]];
            i = 1;
        }
    }
    if (otherTitles.count > i) {
        va_list arg_list;
        va_start(arg_list, block);
        AlertBlock tempBlock;
        while ((tempBlock = va_arg(arg_list, AlertBlock))) {
            if (i >= otherTitles.count) {
                break;
            }
            [alert addAction:[UIAlertAction actionWithTitle:otherTitles[i] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                tempBlock();
            }]];
            i++;
        }
        va_end(arg_list);
        
        for (; i < otherTitles.count; i++) {
            [alert addAction:[UIAlertAction actionWithTitle:otherTitles[i] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            }]];
        }
    }

    if (!viewController) {
        viewController = [alert visibleViewController:nil];
        if (!viewController) {
            return;
        }
    }

    [viewController presentViewController:alert animated:true completion:nil];
}

- (UIViewController *)visibleViewController:(UIViewController *)rootViewController {
    UIViewController *root;
    if (rootViewController) {
        root = rootViewController;
    } else {
        UIViewController *controller  = UIApplication.sharedApplication.delegate.window.rootViewController;
        if (!controller) {
            return nil;
        }
        root = controller;
    }
    UIViewController *presented = root.presentedViewController;
    if (!presented) {
        return root;
    }
    if ([presented isKindOfClass:[UINavigationController class]]) {
        return [self visibleViewController:((UINavigationController *)presented).topViewController];
    }
    if ([presented isKindOfClass:[UITabBarController class]]) {
        return [self visibleViewController:((UITabBarController *)presented).selectedViewController];
    }
    return presented;
}
@end

 二、Swift

调用:

        UIAlertController.showWithTitle("hello")
        UIAlertController.showWithTitle("hello", buttonTitle: "好的") {
            print("好的")
        }
        UIAlertController.showWithTitle("hello", message: nil, rootViewController: nil, cancelButtonTitle: "cancel", otherButtonTitles: ["1", "2"], actionBlocks:nil, {
            print("1")
        },{
            print("2")
        })

UIAlertControllerExtension.swift

import UIKit

typealias LYFAlertBlcok = () -> Void

fileprivate let LYFButtonTitle = "确定"

extension UIAlertController {
    
    /// 显示UIAlertController,只有一个按钮
    ///
    /// - Parameters:
    ///   - title: title
    ///   - message: message,可以为nil
    ///   - buttonTitle: 按钮文字,可以为nil,默认值:"确定"
    ///   - block: 按钮回调,可以为nil
    class func showWithTitle(_ title: String, message: String? = nil, buttonTitle: String? = LYFButtonTitle, block: LYFAlertBlcok? = nil) {
        UIAlertController.showWithTitle(title, message: message, otherButtonTitles: [buttonTitle ?? LYFButtonTitle], actionBlocks: block)
    }

    /**
     显示UIAlertController
     
     @param title title
     @param message message
     @param rootViewController 在哪个UIViewcontroller上显示,可以为nil
     @param cancelButtonTitle 取消按钮文字,为nil则没有取消按钮
     @param otherButtonTitles 其他按钮文字
     @param actionBlocks 响应按钮的block,如果cancelString不为nil,则第一个为cancel按钮的,之后的block依次对应otherTitles的元素
     */
    class func showWithTitle(_ title: String, message: String? = nil, rootViewController: UIViewController? = nil, cancelButtonTitle: String? = nil, otherButtonTitles: [String], actionBlocks: LYFAlertBlcok?...) {
        let alert = UIAlertController(title: title, message: message ?? "", preferredStyle: .alert)
        var i = 0
        if let cancelString = cancelButtonTitle {
            let block: LYFAlertBlcok? = i < actionBlocks.count ? actionBlocks[i] : nil
            alert.addAction(UIAlertAction(title: cancelString, style: .cancel) { _ in
                block?()
            })
            i += 1
        }
        
        for string in otherButtonTitles {
            let block: LYFAlertBlcok? = i < actionBlocks.count ? actionBlocks[i] : nil
            alert.addAction(UIAlertAction(title: string, style: .default) { _ in
                block?()
            })
            i += 1
        }
        
        (rootViewController ?? visibleViewController())?.present(alert, animated: true, completion: nil)
    }

    fileprivate class func visibleViewController(_ rootViewController: UIViewController? = nil) -> UIViewController? {
        var root: UIViewController

        if let rootViewController = rootViewController {
            root = rootViewController
        }
        else {
            let appDelegate = UIApplication.shared.delegate as? AppDelegate

            guard let controller = appDelegate?.window?.rootViewController else {
                return nil
            }

            root = controller
        }

        guard let presented = root.presentedViewController else {
            return root
        }

        if let navigation = presented as? UINavigationController {
            return visibleViewController(navigation.topViewController)
        }
        if let tabBar = presented as? UITabBarController {
            return visibleViewController(tabBar.selectedViewController)
        }

        return presented
    }
}