天天看点

Swift - 封装UIAlertController

UIAlertView 和 UIActionSheet,对于我们来说,一点也不陌生。但是在iOS8 以后,推出UIAlertController后,UIAlertViewh和UIActionSheet就被废弃了。而对于使用的已经很习惯的UIAlertView、UIActionSheet的书写方式来说,UIAlertController的写法,简直麻烦到令人发指。起码我个人是这么觉得的。在此基础上,我在此前的项目中,使用Objective-C封装了一套类似于UIAlertView、UIActionSheet写法的UIAlertController, 使用起来,效果还可以。因为现在用Swift开发,所以将之前的Objective-C版本,翻译成Swift版本。 仅供参考

//
//  CustomAlertController.swift
//  AlertController
//
//  Created by YLJ on 2017/6/19.
//  Copyright © 2017年 YLJ. All rights reserved.
//

import UIKit

// 弹出框样式
enum UIAlertStyle: Int {
    case actionSheet = 0
    case alert = 1
}

class CustomAlertController: NSObject {
    
    // MARK: 私有变量
    // 系统弹出框样式
    private var alertControllerStyle: UIAlertControllerStyle!
    // action 样式
    private var alertActionStyle: UIAlertActionStyle!
    private var alertController: UIAlertController!
    // 标题
    private var ljtitle: String!
    // 消息
    private var ljmessage: String!

    // MARK: 公有属性
    var titleColor: UIColor = UIColor.black {
        didSet {
            if ljtitle != nil && ljtitle.characters.count > 0 {
                changeTitle()
            }
        }
    }
    var messageColor: UIColor = UIColor.black {
        didSet {
            if ljmessage != nil && ljmessage.characters.count > 0 {
                changeMessage()
            }
        }
    }
    var cancelTitleColor: UIColor = UIColor.black {
        didSet {
            let acrion = alertController.actions.first
            acrion?.setValue(cancelTitleColor, forKey: "titleTextColor")
        }
    }
    var otherTitlesColor: UIColor = UIColor.black {
        didSet {
            for (index, value) in alertController.actions.enumerated() {
                if index != 0 {
                    let action = value
                    action.setValue(otherTitlesColor, forKey: "titleTextColor")
                }
            }
        }
    }
    var titleFont: UIFont = UIFont.systemFont(ofSize: 17) {
        didSet {
            if ljtitle != nil && ljtitle.characters.count > 0 {
                changeTitle()
            }
        }
    }
    var messageFont: UIFont = UIFont.systemFont(ofSize: 13) {
        didSet {
            if ljmessage != nil && ljmessage.characters.count > 0 {
                changeMessage()
            }
        }
    }

    // MARK: 初始化方法
    init(vc: UIViewController?=nil, title: String?=nil, message: String?=nil,
         cancelTitle: String?=nil, otherTitles: [String]?=nil, style: UIAlertStyle,
         closure: @escaping ((_ action: UIAlertAction, _ index: Int) -> ())) {
        super.init()
        
        switch style {
        case .actionSheet:
            alertControllerStyle = .actionSheet
            break
        case .alert:
            alertControllerStyle = .alert
            break
        }
        
        // 临时标题,为了防止title与message同时为nil,导致程序崩溃
        var tempTitle = title
        if title == nil && message == nil {
            tempTitle = ""
        }
        alertController = UIAlertController.init(title: tempTitle, message: message, preferredStyle: alertControllerStyle)

        var titles: [String] = []
        if cancelTitle != nil {
            titles.insert(cancelTitle!, at: 0)
        }
        
        if otherTitles != nil {
            titles = titles+otherTitles!
        }
        
        for (ind, value) in titles.enumerated() {
            if (cancelTitle != nil) && (ind == 0) {
                alertActionStyle = .cancel
            } else {
                alertActionStyle = .default
            }
            
            let customAction = UIAlertAction.init(title: value, style: alertActionStyle, handler: {(action) in
                closure(action, ind)
            })
            
            if title != nil {
                ljtitle = title!
                changeTitle()
            }
            
            if message != nil {
                ljmessage = message
                changeMessage()
            }
            
            if alertActionStyle == .cancel {
                customAction.setValue(cancelTitleColor, forKey: "titleTextColor")
            } else {
                customAction.setValue(otherTitlesColor, forKey: "titleTextColor")
            }
            alertController.addAction(customAction)
        }
        
        if vc != nil {
            vc?.present(alertController, animated: true, completion: nil)
        } else {
            UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
        }
    }
    
    // 改变标题
    private func changeTitle() {
        changeText(text: ljtitle, attribute1: NSForegroundColorAttributeName,
                   value1: titleColor, attribute2: NSFontAttributeName,
                   value2: titleFont, range: NSRange(location: 0, length: ljtitle.characters.count),
                   key: "attributedTitle")
    }
    // 改变消息
    private func changeMessage() {
        changeText(text: ljmessage, attribute1: NSForegroundColorAttributeName,
                   value1: messageColor, attribute2: NSFontAttributeName,
                   value2: messageFont, range: NSRange(location: 0, length: ljmessage.characters.count),
                   key: "attributedMessage")
    }
    // 改变文字
    private func changeText(text: String, attribute1: String, value1: Any,
                            attribute2: String, value2: Any, range: NSRange, key: String) {
        let alertControllerStr = NSMutableAttributedString.init(string: text)
        alertControllerStr.addAttributes([attribute1: value1], range: range)
        alertControllerStr.addAttributes([attribute2: value2], range: range)
        alertController.setValue(alertControllerStr, forKey: key)
    }
}