原创:问题解决型文章
创作不易,请珍惜,之后会持续更新,不断完善
个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈哈,这些文章记录了我的IOS成长历程,希望能与大家一起进步
温馨提示:由于简书不支持目录跳转,大家可通过command + F 输入目录标题后迅速寻找到你所需要的内容
目录
- 1、Array 的扩展
- 2、Date 的扩展
- 3、Dictionary 的扩展
- 4、Int 的扩展
- 5、NSMutableAttributedString 的扩展
- 6、NSData 的扩展
- 7、NSObject 的扩展
- 8、Double 的扩展
- 9、Float 的扩展
- 10、CGFloat 的扩展
- 11、String 的扩展
- 12、Timer 的扩展
1、Array 的扩展
public extension Array
arrayJsonString():将数组对象转换成json字符串
func arrayJsonString() -> String? {
if !JSONSerialization.isValidJSONObject(self) {
return nil
}
if let data = try? JSONSerialization.data(withJSONObject: self, options: []),
let string = NSString(data: data, encoding: String.Encoding.utf8.rawValue){
return string as String
}
return nil
}
eachItem(_ callback:((Int, Any)->Void)):遍历返回index和item
openWhiteList.eachItem { (index, item) in
}
func eachItem(_ callback:((Int, Any)->Void)) {
for (index,value) in self.enumerated() {
callback(index,value)
}
}
reduceArray(_ array:[Any], block:((Any) -> Bool)?):过滤数组
/// block: 过滤器回调方法
func reduceArray(_ array:[Any], block:((Any) -> Bool)?) -> [Any]? {
var result = array
if block != nil {
for (_,item) in self.enumerated() {
if (block!(item)) {
result.append(item)
}
}
} else {
result.append(contentsOf: self)
}
return result
}
firstRuleNumber(block: (Any) -> Bool):获取数组中符合规则的第一个数据
func firstRuleNumber(block: (Any) -> Bool) -> Any? {
for (_,item) in self.enumerated() {
if (block(item)) {
return item
}
}
return nil
}
2、Date 的扩展
public extension Date
secondsPerDay:每天有多少秒
var secondsPerDay: TimeInterval {
get {
return 24 * 60 * 60
}
}
secondsPerHour:每小时有多少秒
var secondsPerHour: TimeInterval {
get {
return 60 * 60
}
}
secondsPerMinute:每分钟有多少秒
var secondsPerMinute: TimeInterval {
get {
return 60
}
}
yesterday:昨天
var yesterday: Date {
get {
return self.addingTimeInterval(-secondsPerDay)
}
}
tomorrow:明天
var tomorrow: Date {
get {
return self.addingTimeInterval(secondsPerDay)
}
}
lastWeek:上周
var lastWeek: Date {
get {
return self.addingTimeInterval(-secondsPerDay * 7)
}
}
lastThirtyDays:上个月
var lastThirtyDays: Date {
get {
return self.addingTimeInterval(-secondsPerDay * 30)
}
}
latest(_ day: Int) -> Date:获取间隔一定天数的日期(时间间隔可以是正数或负数)
func latest(_ day: Int) -> Date {
return self.addingTimeInterval(secondsPerDay * Double(day))
}
lastestMonth(_ month: Int) -> Date?:获取间隔一定月份的日期
func lastestMonth(_ month: Int) -> Date? {
var comps = DateComponents()
comps.month = month
if let calender = NSCalendar(calendarIdentifier: .gregorian) {
let mDate = calender.date(byAdding: comps, to: self, options: NSCalendar.Options(rawValue: 0))
return mDate
}
return nil
}
获取年月日时分秒
var year: Int {
return Calendar.current.dateComponents([.year], from: self).year ?? 0 // 默认0点
}
var month: Int {
return Calendar.current.dateComponents([.month], from: self).month ?? 0 // 默认0点
}
var day: Int {
return Calendar.current.dateComponents([.day], from: self).day ?? 0 // 默认0点
}
var hour: Int {
return Calendar.current.dateComponents([.hour], from: self).hour ?? 0 // 默认0点
}
var minute: Int {
return Calendar.current.dateComponents([.minute], from: self).minute ?? 0 // 默认0点
}
var second: Int {
return Calendar.current.dateComponents([.second], from: self).second ?? 0 // 默认0点
}
timeIntervalDay:获取距离当前时间的天数
当self
晚于当前时间24小时整数倍时,返回结果为负数,并且比实际时间长度绝对值小1。时间比较是以毫秒维度比较的,代码执行顺序会产生时间差异,这种情况建议手动处理。
var timeIntervalDay: Int {
return Calendar.current.dateComponents([.day], from: self, to: Date()).day ?? 0 // 默认0点
}
isBetweenFormHour(_ formHour:NSInteger,toHour:NSInteger):判断当前时间是否在两个时间段内
func isBetweenFormHour(_ formHour:NSInteger,toHour:NSInteger) -> Bool {
let dateFrom = self.getCustomDateWith(hour: formHour)
let dateTo = self.getCustomDateWith(hour: toHour)
let currentDate = self
if (currentDate.compare(dateFrom) == .orderedDescending || currentDate.compare(dateFrom) == .orderedSame) && (currentDate.compare(dateTo) == .orderedAscending || currentDate.compare(dateTo) == .orderedSame){
return true
}
return false
}
getCustomDateWith(hour:NSInteger) -> Date:根据小时获取自定义日期
private func getCustomDateWith(hour:NSInteger) -> Date {
let currentDate = self
let currentCalendar = Calendar.init(identifier: .gregorian)
var currentComps = DateComponents()
currentComps = currentCalendar.dateComponents([Calendar.Component.year,Calendar.Component.month,Calendar.Component.day,Calendar.Component.weekday,Calendar.Component.hour,Calendar.Component.month,Calendar.Component.second], from: currentDate)
var resultComps = DateComponents()
resultComps.year = currentComps.year
resultComps.month = currentComps.month
resultComps.day = currentComps.day
resultComps.hour = hour
resultComps.minute = currentComps.minute
let resultCalendar = Calendar.init(identifier: .gregorian)
return resultCalendar.date(from: resultComps)!
}
standerTimeString():标准时间格式 yyyy-MM-dd
func standerTimeString() ->String {
let formate = DateFormatter()
formate.dateFormat = "yyyy-MM-dd"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
standerTimeString():发表时间格式 MM-dd HH:mm
func publishTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "MM-dd HH:mm"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
standerTimeString():草稿时间格式 yyyy.MM.dd HH:mm
func draftTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "yyyy.MM.dd HH:mm"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
detailTimeString():详情时间格式 yyyy-MM-dd HH:mm
func detailTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "yyyy-MM-dd HH:mm"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
yyyymmdd():时间格式 yyyy.MM.dd
func yyyymmdd() -> String {
let formate = DateFormatter()
formate.dateFormat = "yyyy.MM.dd"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
yearTimeString():只有年时间格式 yyyy
func yearTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "yyyy"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
yearTimeString():只有月时间格式 MM
func monthTimeString() ->String {
let formate = DateFormatter()
formate.dateFormat = "MM"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
dayTimeString():只有天时间格式 dd
func dayTimeString() ->String {
let formate = DateFormatter()
formate.dateFormat = "dd"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
hourTimeString():只有小时时间格式 HH
func hourTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "HH"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
minuteTimeString():只有分钟时间格式 mm
func minuteTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "mm"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
secondTimeString():只有秒时间格式 ss
func secondTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "ss"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
hhmmssString():时分秒时间格式 HH:mm:ss
func hhmmssString() -> String {
let formate = DateFormatter()
formate.dateFormat = "HH:mm:ss"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
todayPublishTimeString():今天发布的时间格式 HH:mm
func todayPublishTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "HH:mm"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
liveStartTimeString():带中文的时间格式 MM月dd日 EEE HH:mm
func liveStartTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "MM月dd日 EEE HH:mm"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
weekTimeString():周时间格式 EEE
func weekTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "EEE"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
monthDayTimeString():月天时间格式 MM/dd
func monthDayTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "MM/dd"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
monthDayUnderLineTimeString():月天下划线时间格式 MM-dd
func monthDayUnderLineTimeString() -> String {
let formate = DateFormatter()
formate.dateFormat = "MM-dd"
formate.locale = NSLocale.current
let str = formate.string(from: self)
return str
}
yearAndMonthString():年月时间格式 YYYY年MM月
func yearAndMonthString() -> String {
let formatter = DateFormatter()
formatter.dateFormat = "YYYY年MM月"
formatter.locale = NSLocale.current
let str = formatter.string(from: self)
return str
}
weekString():星期时间格式 星期
func weekString() -> String {
let comp = Calendar.current.dateComponents([.weekday], from: self)
let week = comp.weekday ?? 1
var weekDayStr = ""
switch (week) {
case 1:
weekDayStr = "星期日";
break;
case 2:
weekDayStr = "星期一";
break;
case 3:
weekDayStr = "星期二";
break;
case 4:
weekDayStr = "星期三";
break;
case 5:
weekDayStr = "星期四";
break;
case 6:
weekDayStr = "星期五";
break;
case 7:
weekDayStr = "星期六";
break;
default:
weekDayStr = "";
break;
}
return weekDayStr;
}
dateDisplayString():根据日期比较显示时间格式,从年月日开始比对,隐藏相同项
func dateDisplayString() -> String {
let nowComponents = Calendar.current.dateComponents([.year, .month, .day], from: Date())
let selfComponents = Calendar.current.dateComponents([.year, .month, .day], from: self)
if nowComponents.year == selfComponents.year &&
nowComponents.month == selfComponents.month &&
nowComponents.day == selfComponents.day {// 同天
return todayPublishTimeString()
}
if nowComponents.year == selfComponents.year {// 同年
return self.monthDayUnderLineTimeString()
} else {// 不同年
return self.yearTimeString()
}
}
timeDisplayString():根据日期比较显示时间格式,细化到当天、昨天
func timeDisplayString() -> String {
if Calendar.current.isDateInToday(self) {// 当天: 时间段 + 00:00 - 23:59
return todayPublishTimeString()
} else if Calendar.current.isDateInYesterday(self) {// 昨天 时间段 + 00:00 - 23:59
let time = todayPublishTimeString()
return "昨天 \(time)"
} else {
let now = Date()
let interval = now.timeIntervalSince(self)
// 超过48小时: 星期几 + 时间段 + 00:00 - 23:59
if interval > 3600 * 24 * 2 && interval < 3600 * 24 * 7 {
let time = todayPublishTimeString()
let week = weekString()
return "\(week) \(time)"
}
// 超过一周: xxxx年xx月xx日 + 时间段 + 时间段 + 00:00 - 23:59
return detailTimeString()
}
}
timeIntervalChangeToTimeString(timeInterval:TimeInterval, dateFormat:String?):时间戳转成字符串
func timeIntervalChangeToTimeString(timeInterval:TimeInterval, dateFormat:String?) -> String {
let date:NSDate = NSDate.init(timeIntervalSince1970: timeInterval)
let formatter = DateFormatter.init()
if dateFormat == nil {
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
} else {
formatter.dateFormat = dateFormat
}
return formatter.string(from: date as Date)
}
intelligentDisplayString():NSDate的智能文本输出
func intelligentDisplayString() -> String {
let now = Date()
let interval = now.timeIntervalSince(self)
if interval < 60 {// 60秒之内显示刚刚
return "刚刚"
}
if interval >= 60 && interval < 3600 {// 1小时之内显示n分钟前
return "\(Int(interval / 60))分钟前"
}
if interval >= 3600 && interval < 3600 * 24 {// 1天之内显示n小时前
return "\(Int(interval / 3600))小时前"
}
let nowComponents = Calendar.current.dateComponents([Calendar.Component.year], from: now)
let selfComponents = Calendar.current.dateComponents([Calendar.Component.year], from: self)
if nowComponents.year == selfComponents.year {// 本年度显示MM-dd
return monthDayUnderLineTimeString()
} else {// 非本年显示YYYY-MM-dd
return standerTimeString()
}
}
getDate(dateStr: String, format: String):自定义日期格式
static func getDate(dateStr: String, format: String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale.current
dateFormatter.timeZone = TimeZone.current
dateFormatter.dateFormat = format
let date = dateFormatter.date(from: dateStr)
return date
}
format(to format: String):自定义日期格式
func format(to format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
timestamp: TimeInterval:获取时间戳
var timestamp: TimeInterval {
return self.timeIntervalSince1970
}
isSameDay (date1: Date?, date2: Date?):是否同一天
static func isSameDay (date1: Date?, date2: Date?) -> Bool {
guard date1 != nil else {return false}
guard date2 != nil else {return false}
let calendar = Calendar.current
let comp1 = calendar.dateComponents([.year, .month, .day], from: date1!)
let comp2 = calendar.dateComponents([.year, .month, .day], from: date2!)
return comp1.year == comp2.year && comp1.month == comp2.month && comp1.day == comp2.day
}
3、Dictionary 的扩展
public extension Dictionary
jsonDictionaryString():字典转JSON
func jsonDictionaryString() -> String? {
if !JSONSerialization.isValidJSONObject(self) {
return nil
}
if let data = try? JSONSerialization.data(withJSONObject: self, options: []),
let string = NSString(data: data, encoding: String.Encoding.utf8.rawValue){
return string as String
}
return nil
}
has(key: Key):判断是否包含key
func has(key: Key) -> Bool {
return index(forKey: key) != nil
}
removeAll(keys: [Key])
mutating func removeAll(keys: [Key]) {
keys.forEach({ removeValue(forKey: $0)})
}
mergeWith(_ newDic:[Key:Value]):合并字典,返回新的字典,相同key值会被newDic中的value覆盖
func mergeWith(_ newDic:[Key:Value]) -> [Key:Value] {
var result = self
newDic.forEach { result[$0] = $1 }
return result
}
appendWith(_ newDic:[Key:Value]):添加新字典到当前字典,不返回新字典
mutating func appendWith(_ newDic:[Key:Value]) {
newDic.forEach { self[$0] = $1 }
}
4、Int 的扩展
Int64
public extension Int64
var number:Int64 = 8008
var str = number.ml_numToString()// 8k
number = 8808
str = number.ml_numToString()// 8.8k
numToString():数字显示格式
func numToString() -> String{
let num = Double(self)
if num < 0.0 {
return String(0)
}
switch num {
case 0...999:
let numString = String(format: "%.0f", num)
return "\(numString)"
case 1000...9999:
var numString = String(format: "%.1f", num/1000)
if numString.hasSuffix(".0") {
numString = numString[0..<Int(numString.ml_length - 2)]
}
return "\(numString)k"
default:
var numString = String(format: "%.1f", num/10_000)
if numString.hasSuffix(".0") {
numString = numString[0..<Int(numString.ml_length - 2)]
}
return "\(numString)w"
}
}
Int32
public extension Int32
numToString():数字显示格式
func numToString() -> String {
let int64 = Int64(self)
return int64.numToString()
}
Int
public extension Int
numToString():数字显示格式
func numToString() -> String {
let int64 = Int64(self)
return int64.numToString()
}
secondToRecordString():时间显示格式
var time = 99.ml_secondToRecordString()// 00:01:39
time = 9.ml_secondToRecordString()// 00:00:09
func secondToRecordString() -> String {
var tmphh = "\(self / 3600)" as NSString
if tmphh.length == 1 {
tmphh = NSString(format: "0%@", tmphh)
}
var tmpmm = "\((self/60)%60)" as NSString
if tmpmm.length == 1 {
tmpmm = NSString(format: "0%@", tmpmm)
}
var tmpss = "\(self%60)" as NSString
if tmpss.length == 1 {
tmpss = NSString(format: "0%@", tmpss)
}
return NSString(format: "%@:%@:%@",tmphh,tmpmm,tmpss) as String
}
random:得到一个Int随机数,0到Int类型最大值
public static var random: Int {
get {
return Int.random(withMax: Int.max)
}
}
random(withMax n: Int):获取一个0到n-1的Int随机数
public static func random(withMax n: Int) -> Int {
return Int(arc4random_uniform(UInt32(n)))
}
random(lower min: Int, upper max: Int) -> Int:获取一个min到max的Int随机数
public static func random(lower min: Int, upper max: Int) -> Int {
return Int.random(withMax: max - min + 1) + min
}
5、NSMutableAttributedString 的扩展
public extension NSMutableAttributedString
attributenStringColor:选中字体颜色变红
//text: 所有字符串
//selectedText: 需要变颜色的字符串
//allColor: 字符串本来颜色
//selectedColor: 选中字符串颜色
//font: 字符串字体大小
//selectedFont: 选中字符串字体大小
static func attributenStringColor(text:String,
selectedText: String,
allColor: UIColor,
selectedColor: UIColor,
font: UIFont,
selectedFont:UIFont)->NSMutableAttributedString{
var rangeArray: [NSRange] = [NSRange]()
var lastLength: Int = 0
let attStr = NSMutableAttributedString.init(string: text, attributes: [NSAttributedString.Key.font : font,NSAttributedString.Key.foregroundColor:allColor])
var text = text as NSString
while text.contains(selectedText) {
let rang: NSRange = text.range(of: selectedText)
let rang2 = NSMakeRange(rang.location + lastLength, rang.length)
rangeArray.append(rang2)
lastLength += (rang.length + rang.location )
text = text.substring(from: rang.length + rang.location) as NSString
}
for range1 in rangeArray {
attStr.setAttributes([NSAttributedString.Key.foregroundColor:selectedColor,NSMutableAttributedString.Key.font: selectedFont], range: range1)
}
return attStr
}
attributenStringColor:选中字体颜色变红
//text: 整体字符串
//lineSpace: 行间距
//font: 字图
static func lineSpace(text: String,lineSpace: CGFloat,font: CGFloat)->NSMutableAttributedString {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = lineSpace
let attStr = NSMutableAttributedString.init(string: text, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: font)])
attStr.addAttributes([NSAttributedString.Key.paragraphStyle : paragraphStyle], range: NSMakeRange(0, text.count))
return attStr
}
6、NSData 的扩展
public extension NSData
writeImageDataTofolder:将数据写入到本地文件
enum FolderType: String {
case pickImage = "pickImage"
}
func writeTofolder(_ folderType: FolderType = .pickImage , _ name: String = "", _ nameType:String = ".png") -> String {
guard let docPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentationDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first else {
return ""
}
let savePath = docPath + "/" + folderType.rawValue
if !FileManager.default.fileExists(atPath: savePath) {
do {
try FileManager.default.createDirectory(atPath: savePath, withIntermediateDirectories: true, attributes: nil)
} catch {
return ""
}
}
let saveName = name.isEmpty ? ("\(Date().timeIntervalSince1970)" as NSString).replacingOccurrences(of:".", with: "") : name
let path = savePath + "/" + "\(saveName)" + nameType
self.write(toFile: path, atomically: true)
return path
}
7、NSObject 的扩展
public extension NSObject
fullClassName():完整类名
class func fullClassName() -> String {
return NSStringFromClass(self)
}
className():类名
class func className() -> String {
let className = NSStringFromClass(self)
if let location = className.range(of: ".")?.upperBound {
return String(className[location...])
}
return className
}
8、Double 的扩展
public extension Double
random:得到一个0到1.0的Double随机数(包括1.0)
public static var random:Double {
get {
return Double(arc4random()) / 0xFFFFFFFF
}
}
random(lower min: Double, upper max: Double):获取一个min到max的Double随机数
public static func random(lower min: Double, upper max: Double) -> Double {
return Double.random * (max - min) + min
}
9、Float 的扩展
public extension Float
random:得到一个0到1.0的Float随机数(包括1.0)
public static var random:Float {
get {
return Float(arc4random()) / 0xFFFFFFFF
}
}
random(lower min: Float, upper max: Float):获取一个min到max的Float随机数
public static func random(lower min: Float, upper max: Float) -> Float {
return Float.random * (max - min) + min
}
10、CGFloat 的扩展
extension CGFloat
randomSign:随机获得-1.0或者1.0
public static var randomSign:CGFloat {
get {
return (arc4random_uniform(2) == 0) ? 1.0 : -1.0
}
}
random:得到一个0到1.0的CGFloat随机数(包括1.0)
public static var random:CGFloat {
get {
return CGFloat(Float.random)
}
}
random(lower min: CGFloat, upper max: CGFloat):获取一个min到max的CGFloat随机数
public static func random(lower min: CGFloat, upper max: CGFloat) -> CGFloat {
return CGFloat.random * (max - min) + min
}
11、String 的扩展
字符串内容判断
isEmpty(str: String?):静态方法判断字符串为空
static func isEmpty(str: String?) -> Bool {
guard let v = str else {
return true
}
let leftText = v.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
if leftText == "" {
return true
}
return false
}
isEmptyString() -> Bool:判断字符串为空
func isEmptyString() -> Bool {
let leftText = trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
if leftText == "" {
return true
}
return false
}
isMobile() -> Bool:判断是否为手机号
func isMobile() -> Bool {
let regex = try! NSRegularExpression(pattern: "^1[0-9]{10}$", options: [.caseInsensitive])
return regex.firstMatch(in: self, options:[], range: NSMakeRange(0, self.count)) != nil
}
isEmail() -> Bool:校验邮箱是否合规
func isEmail() -> Bool {
let regex = try! NSRegularExpression(pattern: "^(([a-z0-9_-]+\\.)*)([a-z0-9_-]+)@(([a-z0-9-]+\\.)+)([a-z0-9]{2,6})$", options: [.caseInsensitive])
return regex.firstMatch(in: self, options:[], range: NSMakeRange(0, self.count)) != nil
}
isVerifyCode() -> Bool:校验验证码是否合规
func isVerifyCode() -> Bool {
let regex = try! NSRegularExpression(pattern: "^[0-9]{6}$", options: [.caseInsensitive])
return regex.firstMatch(in: self, options:[], range: NSMakeRange(0, self.count)) != nil
}
vaildPassword() -> (bool: Bool, error: String):校验密码是否合规
func vaildPassword() -> (bool: Bool, error: String) {
if self.count < 6 || self.count > 16{
return (false,"密码长度应该为6到16位")
}
else if self.contains(" "){
return (false,"密码不能包含空格")
}
else if self.contains("\t"){
return (false,"密码不能包含制表符")
}
else if self.contains("\n"){
return (false,"密码不能包含回车")
}
else{
return (true,"")
}
}
containMobile() -> Bool:校验手机号是否合规
func containMobile() -> Bool {
guard let regex = try? NSRegularExpression(pattern: "1[3-8][0-9]{9}", options: [.caseInsensitive]) else {return false}
let matchNum = regex.numberOfMatches(in: self, options: [], range: NSRange(location: 0, length: (self as NSString).length))
return matchNum > 0
}
isChinese() -> Bool:校验是否为中文
func isChinese() -> Bool {
let regex = try! NSRegularExpression(pattern: "^[\\u4e00-\\u9fa5]+$", options: [.caseInsensitive])
return regex.firstMatch(in: self, options:[], range: NSMakeRange(0, self.count)) != nil
}
validateIDCardNumber() -> Bool:验证身份证是否合规
func validateIDCardNumber() -> Bool {
let value = self.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
let length = value.count
if (length == 18) {
let provinceCodeList = ["11","12","13","14","15",
"21","22","23",
"31","32","33","34","35","36","37",
"41","42","43","44","45","46",
"50","51","52","53","54",
"61","62","63","64","65",
"71",
"81","82",
"91"]
let regularExpress = try? NSRegularExpression.init(pattern: "^[0-9]{17}[0-9X]$", options: .caseInsensitive)
if let _ = regularExpress?.firstMatch(in: self, options: .reportProgress, range: NSMakeRange(0, length)) {
// 校验省份是否合规
let province = self.subString(to: 2)
if !provinceCodeList.contains(province) {
return false
}
//判断年月日是否有效
//年份
let strYear = Int(self.subString(from: 6, length: 4))
//月份
let strMonth = Int(self.subString(from: 10, length: 2))
//日
let strDay = Int(self.subString(from: 12, length: 2))
let localZone = NSTimeZone.local
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
dateFormatter.timeZone = localZone
dateFormatter.dateFormat = "yyyy-MM-dd"
let date = dateFormatter.date(from: "\(String(format: "%02d",strYear!))-\(String(format: "%02d",strMonth!))-\(String(format: "%02d",strDay!))")
if date == nil {
return false
}
//加权因子
let R = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
//校验码
let sChecker: [Int8] = [1,0,10,9,8,7,6,5,4,3,2]
var sum = 0
for i in 0...16 {
sum += R[i]*(Int(self.subString(from: i, length: 1)) ?? 0)
}
let verifyStr = self.subString(from: 17, length: 1)
var verifyCode = 0
if verifyStr == "X" {
verifyCode = 10
} else {
verifyCode = Int(verifyStr) ?? 0
}
let mode = sum % 11
if sChecker[mode] == verifyCode {
return true
} else {
return false
}
} else {
return false
}
} else {
return false
}
}
字符串操作
subString(to:Int):截取字符串直到指定终点
func subString(to:Int) -> String {
return subString(from: 0,to: to )
}
subString(from:Int) :从指定起点开始截取字符串
func subString(from:Int) -> String {
return subString(from: from,to: self.count - 1)
}
subString(from:Int,length:Int):从指定起点开始截取一定长度的字符串
func subString(from:Int,length:Int) -> String {
let to = from + length
return subString(from: from,to: to)
}
subString(from:Int,to:Int):截取从指定起点到指定终点范围之内的字符串
func subString(from:Int,to:Int) -> String {
if from >= self.count || to > self.count {
return self
} else {
let startIndex = Index(utf16Offset: from, in: self)
let endIndex = Index(utf16Offset: to, in: self)
let subString = self[startIndex ..< endIndex]
return String(subString)
}
}
limitString(limit: Int):根据指定长度截取字符串
func limitString(limit: Int) -> String {
return subString(to: limit)
}
limitStringWithDot(limit: Int) :根据指定长度截取字符串结尾显示...
func limitStringWithDot(limit: Int) -> String {
let newStr = NSMutableString(string: self)
if limit > -1 && newStr.length > limit {
return newStr.substring(to: limit) + "..."
} else {
return self
}
}
deleteSpace():删除空格
func deleteSpace() -> String {
return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
removeAllSpace():移除所有空格
func removeAllSpace() -> String {
return self.replacingOccurrences(of: " ", with: "", options: .literal, range: nil)
}
deleteLineBreak() :移除所有换行符和制表符
func deleteLineBreak() -> String {
return self.replacingOccurrences(of: "\n", with: " ").replacingOccurrences(of: "\r", with: " ")
}
trimmingSpace():截取掉字符串两端的空格和换行符
func trimmingSpace() -> String {
return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
replaceAllSpace(replacement:String = ""):替换掉字符串中所有空格,默认为移除
func replaceAllSpace(replacement:String = "") -> String {
return self.replacingOccurrences(of: " ", with: replacement, options: .literal, range: nil)
}
replaceLineBreak(replacement:String = " "):替换掉字符串中所有换行符,默认为空格
func replaceLineBreak(replacement:String = " ") -> String {
return self.replacingOccurrences(of: "\n", with: replacement).replacingOccurrences(of: "\r", with: replacement)
}
decodeUrl():URL解码
func decodeUrl() -> String {
let mutStr = NSMutableString(string: self)
mutStr.replaceOccurrences(of: "+", with: " ", options: NSString.CompareOptions.literal, range: NSMakeRange(0, mutStr.length))
return mutStr.removingPercentEncoding ?? ""
}
encodeUrl():URL编码
func encodeUrl() -> String {
let generalDelimitersToEncode = "!$&'()*+,;=:#[]@/?"
var allowedCharacterSet = CharacterSet.urlQueryAllowed
allowedCharacterSet.remove(charactersIn: generalDelimitersToEncode)
return self.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? ""
}
urlSetComponents(_ params:[String:String]):URL 字符串拼接
func urlSetComponents(_ params:[String:String]) -> String {
var queryItems = [URLQueryItem]()
params.each { (key, value) in
let queryItem = URLQueryItem(name: key, value: "\(value)")
queryItems.append(queryItem)
}
let urlComponents = NSURLComponents(string: self)
urlComponents?.queryItems = queryItems
return urlComponents?.url?.absoluteString ?? ""
}
urlParameters():从urlString中截取出参数,参数必须经过url编码
func urlParameters() -> [String: String]? {
guard let url = URL(string: self),
let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else { return nil }
return queryItems.reduce(into: [String: String](), { (result, item) in
result[item.name] = item.value?.decodeUrl()
})
}
rangesOfRegex(_ regex: String):获取指定正则条件的range数组
func rangesOfRegex(_ regex: String) -> [NSRange] {
let expression = try? NSRegularExpression(pattern: regex, options: .caseInsensitive)
let matches = expression?.matches(in: self, options: .reportProgress, range: NSMakeRange(0, self.count))
return matches?.map({ (match) -> NSRange in
return match.range
}) ?? []
}
rangesOfString(_ target: String):获取指定字符串的range数组
func rangesOfString(_ target: String) -> [NSRange] {
return self.rangesOfRegex(target)
}
rangesOfNumber():获取字符串中数字的range数组
func rangesOfNumber() -> [NSRange] {
return self.rangesOfRegex("[0-9]+")
}
pregReplace(pattern: String, with: String):使用正则表达式替换
func pregReplace(pattern: String, with: String,
options: NSRegularExpression.Options = []) -> String {
let regex = try! NSRegularExpression(pattern: pattern, options: options)
return regex.stringByReplacingMatches(in: self, options: [],
range: NSMakeRange(0, self.count),
withTemplate: with)
}
subRangeOfUrl():网址检查
func subRangeOfUrl() -> [NSRange] {
let linkPattern = "((http[s]{0,1}|ftp)://[a-zA-Z0-9\\-.]+(?::(\\d+))?(?:(?:/[a-zA-Z0-9\\-._?,'+\\&%$=~*!():@\\\\]*)+)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)"
guard let regex = try? NSRegularExpression(pattern: linkPattern, options: NSRegularExpression.Options.caseInsensitive) else {return []}
let resultArr = regex.matches(in: self, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSRange(location: 0, length: (self as NSString).length))
var rangeArr = [NSRange]()
for item in resultArr {
rangeArr.append(item.range)
}
return rangeArr
}
subscript (r: Range<Int>):String使用下标截取字符串,比如"示例字符串"[0..<2] 结果是 "示例"
subscript (r: Range<Int>) -> String {
get {
let startIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
let endIndex = self.index(self.startIndex, offsetBy: r.upperBound)
return String(self[startIndex..<endIndex])
}
}
removeEmoji():移除emoji
func removeEmoji() -> String {
let pattern = "[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]"
return self.pregReplace(pattern: pattern, with: "")
}
字符串尺寸
heightForTextSize(fontSize: CGFloat, width: CGFloat):普通系统文本的高度
func heightForTextSize(fontSize: CGFloat, width: CGFloat) -> CGFloat {
let font = UIFont.systemFont(ofSize: fontSize)
return self.heightWithFont(font: font, width: width)
}
widthForTextSize(fontSize: CGFloat, height: CGFloat = 15):普通系统文本的高度
func widthForTextSize(fontSize: CGFloat, height: CGFloat = 15) -> CGFloat {
let font = UIFont.systemFont(ofSize: fontSize)
return self.widthWithFont(font: font,height: height)
}
heightWithBoldForTextSize(fontSize: CGFloat, width: CGFloat):加粗系统文本的高度
func heightWithBoldForTextSize(fontSize: CGFloat, width: CGFloat) -> CGFloat {
let font = UIFont.boldSystemFont(ofSize: fontSize)
return self.heightWithFont(font: font, width: width)
}
widthWithBoldForTextSize(fontSize: CGFloat, height: CGFloat = 15):加粗系统文本的宽度
func widthWithBoldForTextSize(fontSize: CGFloat, height: CGFloat = 15) -> CGFloat {
let font = UIFont.boldSystemFont(ofSize: fontSize)
return self.widthWithFont(font: font,height: height)
}
heightWithFont(font: UIFont, width: CGFloat):计算字体的高度
func heightWithFont(font: UIFont, width: CGFloat) -> CGFloat {
let rect = NSString(string: self).boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
return ceil(rect.height)
}
widthWithFont(font: UIFont, height: CGFloat = 15):计算字体的宽度
func widthWithFont(font: UIFont, height: CGFloat = 15) -> CGFloat {
let rect = NSString(string: self).boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: height), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
return ceil(rect.width)
}
boundingSize():计算字体尺寸
func boundingSize(withConstraintSize size: CGSize, font: UIFont, lineBreakMode: NSLineBreakMode = .byWordWrapping, option: NSStringDrawingOptions = .usesLineFragmentOrigin, context: NSStringDrawingContext? = nil) -> CGSize{
return boundingRect(withSize: size, font: font, lineBreakMode: lineBreakMode, option: option, context: context).size
}
boundingRect():计算字体尺寸的实现方法
func boundingRect(withSize size: CGSize, font: UIFont, lineBreakMode: NSLineBreakMode = .byWordWrapping, option: NSStringDrawingOptions = .usesLineFragmentOrigin, context: NSStringDrawingContext? = nil) -> CGRect {
let text = self as NSString
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = lineBreakMode;
let attributes = [
NSAttributedString.Key.font:font,
NSAttributedString.Key.paragraphStyle:paragraphStyle
]
return text.boundingRect(with: size, options: option, attributes: attributes, context: context)
}
字符串转对象
stringToDictionary():字符串转字典
func stringToDictionary() -> [String : Any]? {
var result: [String : Any]?
guard !self.isEmpty else { return result }
guard let dataSelf = self.data(using: .utf8) else {
return result
}
if let dic = (try? JSONSerialization.jsonObject(with: dataSelf, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String : Any] {
result = dic
}
return result
}
stringToArray():字符串转数组
func stringToArray() -> [Any]? {
var result: [Any]?
guard !self.isEmpty else { return result }
guard let dataSelf = self.data(using: .utf8) else {
return result
}
if let array = (try? JSONSerialization.jsonObject(with: dataSelf, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [Any] {
result = array
}
return result
}
toDouble():字符串转Double类型
func toDouble() -> Double {
return Double(self) ?? 0
}
toFloat():字符串转Float类型
func toFloat() -> Float {
return Float(toDouble())
}
toCGFloat():字符串转CGFloat类型
func toCGFloat() -> CGFloat {
return CGFloat(toDouble())
}
toInt():字符串转Int类型
func toInt() -> Int {
return Int(toDouble())
}
pinyinString():先转换为带音标的拼音,然后去掉音标
func pinyinString() -> String? {
let mutableString = NSMutableString(string: self)
if CFStringTransform(mutableString, nil, kCFStringTransformMandarinLatin, false) {
if CFStringTransform(mutableString, nil, kCFStringTransformStripDiacritics, false) {
return NSString(string: mutableString) as String
}
}
return nil
}
firstChar():第一个字符
func firstChar() -> String {
guard let first = self.trimmingCharacters(in: CharacterSet.whitespaces).first else {return ""}
return "\(first)".uppercased()
}
返回NSAttributedString
setColor(subString: String,withColor color: UIColor,withFont font: UIFont):设置子字符串属性字体
func setColor(subString: String,withColor color: UIColor,withFont font: UIFont) -> NSMutableAttributedString {
let tempNSString: NSString = self as NSString
let range = tempNSString.range(of: subString)
return self.setColor(range: range, withColor: color, withFont: font)
}
setColor(range: NSRange, withColor: UIColor, withFont: UIFont):设置某个范围内的属性字体
func setColor(range: NSRange, withColor: UIColor, withFont: UIFont) -> NSMutableAttributedString {
let tempNSString: NSString = self as NSString
let attributedString = NSMutableAttributedString(string: tempNSString as String)
attributedString.addAttribute(NSAttributedString.Key.font, value: withFont, range: range)
attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: withColor, range: range)
return attributedString
}
attributedStringWithLineSpacing(lineSpacing: CGFloat):字符串配置文字行间距
func attributedStringWithLineSpacing(lineSpacing: CGFloat) -> NSMutableAttributedString {
let attributedString = NSMutableAttributedString(string: self)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = lineSpacing
attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, (self as NSString).length))
return attributedString
}
字符串哈希值
filePathSha256():文件路径哈希值
func filePathSha256() -> String {
let fileManager = FileManager.default
if let url = URL.init(string: self) {
if fileManager.fileExists(atPath: url.path) {
let txtData = fileManager.contents(atPath: url.path)
return hexStringFromData(input: digest(input: txtData! as NSData))
}
}
return ""
}
hexStringFromData(input: NSData):从数据中获取到哈希字符串
private func hexStringFromData(input: NSData) -> String {
var bytes = [UInt8](repeating: 0, count: input.length)
input.getBytes(&bytes, length: input.length)
var hexString = ""
for byte in bytes {
hexString += String(format:"%02x", UInt8(byte))
}
return hexString
}
digest(input : NSData):获取数据的SHA256加密
import CommonCrypto
private func digest(input : NSData) -> NSData {
let digestLength = Int(CC_SHA256_DIGEST_LENGTH)
var hash = [UInt8](repeating: 0, count: digestLength)
CC_SHA256(input.bytes, UInt32(input.length), &hash)
return NSData(bytes: hash, length: digestLength)
}
12、Timer 的扩展
public extension Timer
schedule(intervalFromNow: TimeInterval, block: @escaping () -> ()):只执行一次的计时器
@discardableResult
class func schedule(intervalFromNow: TimeInterval, block: @escaping () -> ()) -> Timer {
let actor = TimerActor(block: block)
let timer = Timer.init(timeInterval: intervalFromNow, target: actor, selector: #selector(actor.fire), userInfo: nil, repeats: false)
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
return timer
}
schedule(every interval: TimeInterval, block: @escaping () -> ()):重复执行的计时器
@discardableResult
class func schedule(every interval: TimeInterval, block: @escaping () -> ()) -> Timer {
let actor = TimerActor(block: block)
let timer = Timer.init(timeInterval: interval, target: actor, selector: #selector(fire), userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
return timer
}
TimerActor:计时器的中介者对象
private class TimerActor {
var block: () -> ()
init(block: @escaping () -> ()) {
self.block = block
}
@objc dynamic func fire() {
block()
}
}
网友评论