// // String+Extension.swift // QuickSearchLocation // // Created by Destiny on 2024/4/15. // import Foundation import UIKit // MARK: - 五、字符串UI的处理 extension String { // MARK: 9.1、判断是否全是空白,包括空白字符和换行符号,长度为0返回true /// 判断是否全是空白,包括空白字符和换行符号,长度为0返回true public var isBlank: Bool { return self.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines) == "" } // MARK: 5.1、对字符串(多行)指定出字体大小和最大的 Size,获取 (Size) /// 对字符串(多行)指定出字体大小和最大的 Size,获取展示的 Size /// - Parameters: /// - font: 字体大小 /// - size: 字符串的最大宽和高 /// - Returns: 按照 font 和 Size 的字符的Size public func rectSize(font: UIFont, size: CGSize) -> CGSize { let attributes = [NSAttributedString.Key.font: font] /** usesLineFragmentOrigin: 整个文本将以每行组成的矩形为单位计算整个文本的尺寸 usesFontLeading: usesDeviceMetrics: @available(iOS 6.0, *) truncatesLastVisibleLine: */ let option = NSStringDrawingOptions.usesLineFragmentOrigin let rect: CGRect = self.boundingRect(with: size, options: option, attributes: attributes, context: nil) return rect.size } // MARK: 5.2、对字符串(多行)指定字体及Size,获取 (高度) /// 对字符串指定字体及Size,获取 (高度) /// - Parameters: /// - font: 字体的大小 /// - size: 字体的size /// - Returns: 返回对应字符串的高度 public func rectHeight(font: UIFont, size: CGSize) -> CGFloat { return rectSize(font: font, size: size).height } // MARK: 5.3、对字符串(多行)指定字体及Size,获取 (宽度) /// 对字符串指定字体及Size,获取 (宽度) /// - Parameters: /// - font: 字体的大小 /// - size: 字体的size /// - Returns: 返回对应字符串的宽度 public func rectWidth(font: UIFont, size: CGSize) -> CGFloat { return rectSize(font: font, size: size).width } // MARK: 5.4、对字符串(单行)指定字体,获取 (Size) /// 对字符串(单行)指定字体,获取 (Size) /// - Parameter font: 字体的大小 /// - Returns: 返回单行字符串的 size public func singleLineSize(font: UIFont) -> CGSize { let attrs = [NSAttributedString.Key.font: font] return self.size(withAttributes: attrs as [NSAttributedString.Key: Any]) } // MARK: 5.5、对字符串(单行)指定字体,获取 (width) /// 对字符串(单行)指定字体,获取 (width) /// - Parameter font: 字体的大小 /// - Returns: 返回单行字符串的 width public func singleLineWidth(font: UIFont) -> CGFloat { let attrs = [NSAttributedString.Key.font: font] return self.size(withAttributes: attrs as [NSAttributedString.Key: Any]).width } // MARK: 5.6、对字符串(单行)指定字体,获取 (Height) /// 对字符串(单行)指定字体,获取 (height) /// - Parameter font: 字体的大小 /// - Returns: 返回单行字符串的 height public func singleLineHeight(font: UIFont) -> CGFloat { let attrs = [NSAttributedString.Key.font: font] return self.size(withAttributes: attrs as [NSAttributedString.Key: Any]).height } // MARK: 5.7、字符串通过 label 根据高度&字体 —> Size /// 字符串通过 label 根据高度&字体 ——> Size /// - Parameters: /// - height: 字符串最大的高度 /// - font: 字体大小 /// - Returns: 返回Size public func sizeAccording(width: CGFloat, height: CGFloat = CGFloat(MAXFLOAT), font: UIFont) -> CGSize { if self.isBlank {return CGSize(width: 0, height: 0)} let rect = CGRect(x: 0, y: 0, width: width, height: height) let label = UILabel(frame: rect).font(font).text(self).line(0) return label.sizeThatFits(rect.size) } // MARK: 5.8、字符串通过 label 根据高度&字体 —> Width /// 字符串通过 label 根据高度&字体 ——> Width /// - Parameters: /// - height: 字符串最大高度 /// - font: 字体大小 /// - Returns: 返回宽度大小 public func widthAccording(width: CGFloat, height: CGFloat = CGFloat(MAXFLOAT), font: UIFont) -> CGFloat { if self.isBlank {return 0} let rect = CGRect(x: 0, y: 0, width: width, height: height) let label = UILabel(frame: rect).font(font).text(self).line(0) return label.sizeThatFits(rect.size).width } // MARK: 5.9、字符串通过 label 根据宽度&字体 —> height /// 字符串通过 label 根据宽度&字体 ——> height /// - Parameters: /// - width: 字符串最大宽度 /// - font: 字体大小 /// - Returns: 返回高度大小 public func heightAccording(width: CGFloat, height: CGFloat = CGFloat(MAXFLOAT), font: UIFont) -> CGFloat { if self.isBlank {return 0} let rect = CGRect(x: 0, y: 0, width: width, height: height) let label = UILabel(frame: rect).font(font).text(self).line(0) return label.sizeThatFits(rect.size).height } // MARK: 5.10、字符串根据宽度 & 字体 & 行间距 —> Size /// 字符串根据宽度 & 字体 & 行间距 ——> Size /// - Parameters: /// - width: 字符串最大的宽度 /// - heiht: 字符串最大的高度 /// - font: 字体的大小 /// - lineSpacing: 行间距 /// - Returns: 返回对应的size public func sizeAccording(width: CGFloat, height: CGFloat = CGFloat(MAXFLOAT), font: UIFont, lineSpacing: CGFloat) -> CGSize { if self.isBlank {return CGSize(width: 0, height: 0)} let rect = CGRect(x: 0, y: 0, width: width, height: CGFloat(MAXFLOAT)) let label = UILabel(frame: rect).font(font).text(self).line(0) let attrStr = NSMutableAttributedString(string: self) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = lineSpacing attrStr.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, self.count)) label.attributedText = attrStr return label.sizeThatFits(rect.size) } // MARK: 5.11、字符串根据宽度 & 字体 & 行间距 —> width /// 字符串根据宽度 & 字体 & 行间距 ——> width /// - Parameters: /// - width: 字符串最大的宽度 /// - heiht: 字符串最大的高度 /// - font: 字体的大小 /// - lineSpacing: 行间距 /// - Returns: 返回对应的 width public func widthAccording(width: CGFloat = CGFloat(MAXFLOAT), height: CGFloat, font: UIFont, lineSpacing: CGFloat) -> CGFloat { if self.isBlank {return 0} let rect = CGRect(x: 0, y: 0, width: width, height: height) let label = UILabel(frame: rect).font(font).text(self).line(0) let attrStr = NSMutableAttributedString(string: self) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = lineSpacing attrStr.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, self.count)) label.attributedText = attrStr return label.sizeThatFits(rect.size).width } // MARK: 5.12、字符串根据宽度 & 字体 & 行间距 —> height /// 字符串根据宽度 & 字体 & 行间距 ——> height /// - Parameters: /// - width: 字符串最大的宽度 /// - heiht: 字符串最大的高度 /// - font: 字体的大小 /// - lineSpacing: 行间距 /// - Returns: 返回对应的 height public func heightAccording(width: CGFloat, height: CGFloat = CGFloat(MAXFLOAT), font: UIFont, lineSpacing: CGFloat) -> CGFloat { if self.isBlank {return 0} let rect = CGRect(x: 0, y: 0, width: width, height: height) let label = UILabel(frame: rect).font(font).text(self).line(0) let attrStr = NSMutableAttributedString(string: self) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = lineSpacing attrStr.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, self.count)) label.attributedText = attrStr return label.sizeThatFits(rect.size).height } } // MARK: - Base64 编解码 extension String { var decode: String { get { guard let decodeResult = self.base64String(encode: false) else { return "" } return decodeResult } } // Base64 编解码 /// Base64 编解码 /// - Parameter encode: true:编码 false:解码 /// - Returns: 编解码结果 func base64String(encode: Bool) -> String? { guard encode else { // 1.解码 guard let decryptionData = Data(base64Encoded: self, options: .ignoreUnknownCharacters) else { return nil } return String(data: decryptionData, encoding: .utf8) } // 2.编码 guard let codingData = self.data(using: .utf8) else { return nil } return codingData.base64EncodedString() } // func decode() -> String? { // // return self.base64String(encode: false) // } }