Swift 引入 全局常量 全局函数 宏 和 类似pch的文件

2019-09
注意导入头文件
import UIKit

// Swift 定义 全局常量 全局函数 宏 类似pch的文件

// 在Swift中如何对常用的工具方法进行定义呢?
// Swift中不支持#define语法,只能依赖Swift自身的特性来实现:
// 一般的有如下几种方式: 1. 常量 2. 全局函数 3. 计算属性 4. 闭包类型的常量

// MARK: - 全局函数
// 写在class类外面的都是全局函数. 说明https://www.jianshu.com/p/d48cf6529541
// 官方文档:https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html


// MARK: - 常量

// MARK: - 沙盒相关

/// 获取沙盒Document路径
let k_Document_Path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
/// 获取沙盒Cache路径
let k_Cache_Path = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first
/// 获取沙盒temp路径
let k_Temp_Path = NSTemporaryDirectory()
/// 返回 用户默认数据库 共享默认值对象
let k_User_Defaults = UserDefaults.standard

// MARK: - 代码缩写

let k_App_Shared = UIApplication.shared
let k_APP_KeyWindow = UIApplication.shared.keyWindow
let k_App_Delegate = UIApplication.shared.delegate
let k_App_NotificationCenter = NotificationCenter.default
let k_App_RootViewController = UIApplication.shared.delegate?.window??.rootViewController

// MARK: - 判断当前的 设备 语言

// 判断是否为iPhone
let k_Device_Is_iPhone = (UI_USER_INTERFACE_IDIOM() == .phone)
// 判断是否为iPad
let k_Device_Is_iPad = (UI_USER_INTERFACE_IDIOM() == .pad)
// 获取当前语言
let k_App_Current_Language = Locale.preferredLanguages[0]

// MARK: - 获取屏幕大小

let k_Screen_Bounds = UIScreen.main.bounds
let k_Screen_Size = UIScreen.main.bounds.size
let k_Screen_Width = UIScreen.main.bounds.size.width
let k_Screen_Height = UIScreen.main.bounds.size.height

// MARK: - 机型判断

// userInterfaceIdiom 当前设备上使用的接口样式。
/// 对于通用应用程序,可以使用此属性为特定类型的设备定制应用程序的行为。
let k_IS_IPHONE = (UIDevice.current.userInterfaceIdiom == .phone)

let k_IPHONE_5 = (k_IS_IPHONE && k_Screen_Height == 568.0)
let k_IPHONE_6 = (k_IS_IPHONE && k_Screen_Height == 667.0)
let k_IPHONE_6_PLUS = (k_IS_IPHONE && k_Screen_Height == 736.0)
let k_IPHONE_X = (k_IS_IPHONE && k_Screen_Height == 812.0)

// MARK: - 获取状态栏、标题栏、导航栏高度

// 1.导航栏高度 88,非iPoneX手机为 64
// 2.状态栏高度 44,非iPoneX手机为 20
// 3.tabar高度 83,非iPhoneX手机为 49
// navigationBarHeight默认高度44 (iPhoneX 88 = 44 + 44)
// tabBarHeight默认高度49     (iPhoneX 83 = 49 + 34)
let k_Status_Bar_Height: CGFloat = UIApplication.shared.statusBarFrame.size.height
let k_Navigation_Bar_Height: CGFloat =  k_IPHONE_X ? 44 + 44 : 44
let K_TabBar_Height: CGFloat = k_IPHONE_X ? 49 + 34 : 49

// MARK: - iPhoneX 安全区域高度

/// 安全区域 顶部高度
let k_Safe_Area_Top_Height = k_IPHONE_X ? 44 : 0
/// 安全区域 底部高度
let k_Safe_Area_Bottom_Height = k_IPHONE_X ? 34 : 0

// MARK: - 适配不同机型的 宽 和 高

// 适配机型: 宽 350 375 414       高 568 667 736

/// 宽度 按比例放大后值
func k_Fit_Width(_ width: CGFloat) -> CGFloat {
    // 屏幕宽度 与最小的iPhone 6的屏幕宽度的比值 乘以传入参数的宽度,得到自动适配后的宽度
    // 此时得到的比值大于1.0
    return width * UIScreen.main.bounds.size.width / 375
}
/// 高度 按比例放大后值
func k_Fit_Heigth(_ height: CGFloat) -> CGFloat {
    return height * UIScreen.main.bounds.size.height / 667
}

// MARK: - 系统版本相关

/// APP版本号
let k_App_Version = Bundle.main.infoDictionary?["CFBundleShortVersionString"]
/// 当前系统版本号
let k_System_Version = (UIDevice.current.systemVersion as NSString).floatValue
/// 检测用户版本号
let k_iOS_12 = (k_System_Version >= 12.0)
let k_iOS_11 = (k_System_Version >= 11.0 && k_System_Version < 12.0)
let k_iOS_10 = (k_System_Version >= 10.0 && k_System_Version < 11.0)
let k_iOS_9 = (k_System_Version >= 9.0 && k_System_Version < 10.0)
let k_iOS_8 = (k_System_Version >= 8.0 && k_System_Version < 9.0)
let k_iOS_12_Later = (k_System_Version >= 12.0)
let k_iOS_11_Later = (k_System_Version >= 11.0)
let k_iOS_10_Later = (k_System_Version >= 10.0)
let k_iOS_9_Later = (k_System_Version >= 9.0)
let k_iOS_8_Later = (k_System_Version >= 8.0)

// MARK: - 全局函数 方法

// MARK: - 颜色相关

/// 自定义颜色 RGB
func k_Color_RGB(_ r:CGFloat, g:CGFloat, b:CGFloat) -> UIColor {
    
    return UIColor(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1.0)
}

/// 自定义颜色 RGBA
func k_Color_RGBA(_ r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat) -> UIColor {
    
    return UIColor(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: a)
}

/// 自定义颜色 HEXA
func k_Color_HEXA(hexValue: Int, a: CGFloat) -> (UIColor) {
    
    return UIColor(red: ((CGFloat)((hexValue & 0xFF0000) >> 16)) / 255.0,
                   green: ((CGFloat)((hexValue & 0xFF00) >> 8)) / 255.0,
                   blue: ((CGFloat)(hexValue & 0xFF)) / 255.0,
                   alpha: a)
}

/// 自定义 随机颜色
func k_Color_Random() -> UIColor {

    return UIColor(red: CGFloat(arc4random() % 256) / 255.0,
                   green: CGFloat(arc4random() % 256) / 255.0,
                   blue: CGFloat(arc4random() % 256) / 255.0,
                   alpha: 1.0)
}

/// 自定义 随机颜色 浅色
func k_Color_Random_Light() -> UIColor {
    
    return UIColor(red: ((CGFloat(arc4random() % 256) / 255.0) * 0.7 + 0.3),
                   green: ((CGFloat(arc4random() % 256) / 255.0) * 0.7 + 0.3),
                   blue: ((CGFloat(arc4random() % 256) / 255.0) * 0.7 + 0.3),
                   alpha: 1.0)
}

// MARK: - 屏幕像素点尺寸相关

/// 获取屏幕的大小 如果是用像素点表示的,就转换为用标准点来表示
func k_Screen_Size_Pixels_To_Point() -> CGSize {
    
    // 返回一个布尔值,该值指示接收方是否实现或继承能够响应指定消息的方法。
    // nativeBounds 物理屏幕的边框,以像素为单位。
    let isResponds = UIScreen.main.responds(to: #selector(getter: UIScreen.nativeBounds))
    // nativeBounds 物理屏幕的边框,以像素为单位 尺寸的宽度.
    // nativeScale 物理屏幕的原生比例因子。
    // 此处是将手机像素宽度 转换为 开发用的点宽度
    let width = UIScreen.main.nativeBounds.size.width / UIScreen.main.nativeScale
    let height = UIScreen.main.nativeBounds.size.height / UIScreen.main.nativeScale
    let size = UIScreen.main.bounds.size
    
    if isResponds == true {
        return CGSize(width: width, height: height)
    } else {
        return size
    }
}

//    // 同样的表达效果,用三目运算符来表示,如下.
//    let k_Screen_Size_Pixels_To_Point = UIScreen.main.responds(to: #selector(getter: UIScreen.nativeBounds)) ? CGSize(width: UIScreen.main.nativeBounds.size.width / UIScreen.main.nativeScale, height: UIScreen.main.nativeBounds.size.height / UIScreen.main.nativeScale) : UIScreen.main.bounds.size

// MARK: - 通知相关

/// 注册通知
func k_Notification_Add(observer: Any, selector: Selector, name: String) {
    
    return NotificationCenter.default.addObserver(observer, selector: selector, name: Notification.Name(rawValue: name), object: nil)
}
/// 发送通知
func k_Notification_Post(name: String, object: Any) {
    
    return NotificationCenter.default.post(name: Notification.Name(rawValue: name), object: object)
}
/// 移除通知
func k_Notification_Remove(observer: Any, name: String) {
    
    return NotificationCenter.default.removeObserver(observer, name: Notification.Name(rawValue: name), object: nil)
}

// MARK: - 字符串 数组 字典 是否为空

/// 字符串是否为空
///
/// - Parameter str: NSString 类型 和 子类
/// - Returns: Bool类型 true or false
func k_Is_Empty_String(_ str: String!) -> Bool {
    if str.isEmpty {
        return true
    }
    if str == nil {
        return true
    }
    if str.count < 1 {
        return true
    }
    if str == "(null)" {
        return true
    }
    if str == "null" {
        return true
    }
    return false
}



/// 数组是否为空
///
/// - Parameter array: NSArray 类型 和 子类
/// - Returns: Bool类型 true or false
func k_Is_Empty_Array(_ array: [String]) -> Bool {
    // 将数组中的所有元素连接起来,返回连接好的字符串
    let str: String! = array.joined(separator: "")
    if str == nil {
        return true
    }
    if str == "(null)" {
        return true
    }
    if array.count == 0 {
        return true
    }
    if array.isEmpty {
        return true
    }
    return false
}




/// 字典是否为空
///
/// - Parameter dict: NSDictionary 类型 和 子类
/// - Returns: Bool类型 true or false
func k_Is_Empty_Dictionary(_ dict: NSDictionary) -> Bool {
    let str: String! = "\(dict)"
    if str == nil {
        return true
    }
    if str == "(null)" {
        return true
    }
    if dict .isKind(of: NSNull.self) {
        return true
    }
    if dict.allKeys.count == 0 {
        return true
    }
    return false
}

// MARK: - 自定义(可变参数)打印函数

// 官方文档
// https://developer.apple.com/documentation/swift/1539920-debugprint

/// 全局函数 自定义(可变参数)打印函数
///
/// - Parameters:
///   - items: 项目:要打印的零个或多个项目。
///   - separator: 分隔符:要在每个项目之间打印的字符串。默认值是单个空格(" ")。
///   - terminator: 终止符:打印完所有项目后要打印的字符串。默认值是换行符 \n ("\n")。
///   - file: 调用打印方法时 打印方法所在文件的文件路径
///   - function: 当前方法名
///   - line: 当前行号
func k_My_Log(_ items: Any...,
    separator: String = " ",
    terminator: String = "\n",
    file: String = #file,
    function: String = #function,
    line: Int = #line)
{
    #if DEBUG
    
    // 方法一
    
    //    // 由于items是一个数组,所以打印出来最外层会是一个大括号[].
    //    // 如果不怕打印结果有大括号[4, "abc", [1, 2, 3]],可以直接一句话写成这样.
    //    print("\n[文件名]:[\((file as NSString).lastPathComponent)]\n[方法名]:[\(function)]\n[行号]:[\(line)]\n", items)
    
    
    // 方法二
    
    let filenime = (file as NSString).lastPathComponent
    
    // print函数,每行末尾默认添加终止符terminator.终止符的默认值是 换行符"\n";
    // 所以不用再手动添加terminator终止符,也不用再print函数的末尾手写"\n".
    // 如果需要多加上一个换行符,就在末尾手写"\n"
    print("\n[文件名]:[\(filenime)]\n[方法名]:[\(function)]\n[行号]:[\(line)]")
    
    var i = 0
    let j = items.count
    for item in items {
        i += 1
        
        // 重点:
        // 当有多个需要打印的参数时,通过三目运算符判断 终止符terminator 此时的实际值
        //   - separator: 分隔符:要在每个项目之间打印的字符串。默认值是单个空格(" ")。
        //   - terminator: 终止符:打印完所有项目后要打印的字符串。默认值是换行符 \n ("\n")。
        print(item, terminator: i == j ? terminator: separator)
        
    }
    
    //换行,即打印一个空行.
    print()
    
    #endif
    
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容