206 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Swift
		
	
	
	
		
		
			
		
	
	
			206 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Swift
		
	
	
	
|  | // | |||
|  | //  MWIconFont.swift | |||
|  | //  Test | |||
|  | // | |||
|  | //  Created by MYK on 2019/5/2. | |||
|  | //  Copyright © 2019 MYK. All rights reserved. | |||
|  | // | |||
|  | 
 | |||
|  | import UIKit | |||
|  | 
 | |||
|  | /// IconFont | |||
|  | @objcMembers open class MWIconFont: UIFont, @unchecked Sendable { | |||
|  |     static func printIconCodeEnum() { | |||
|  |             guard let fileURL = Bundle.main.url(forResource: "iconfont", withExtension: "json"), | |||
|  |                   let data = try? Data(contentsOf: fileURL), | |||
|  |                   let dict = try? JSONSerialization.jsonObject(with: data) as? [String: Any], | |||
|  |                   let root = try? JSONDecoder().decode(IconFontRootModel.self, from: data) else { | |||
|  |                 print("Error loading or parsing JSON file") | |||
|  |                 return | |||
|  |             } | |||
|  |              | |||
|  |             let list = root.glyphs | |||
|  |             var set: [String] = [] | |||
|  |              | |||
|  |             for obj in list { | |||
|  |                 // Convert name to camelCase and make first character lowercase | |||
|  |                 var name = obj.name | |||
|  |                     .replacingOccurrences(of: "-", with: "_") | |||
|  |                     .replacingOccurrences(of: " ", with: "_") | |||
|  |                  | |||
|  |                 // Simple camelCase conversion (you might need a more sophisticated version) | |||
|  |                 let components = name.components(separatedBy: "_") | |||
|  |                 name = components.enumerated().map { (index, component) in | |||
|  |                     index == 0 ? component.lowercased() : component.capitalized | |||
|  |                 }.joined() | |||
|  |                  | |||
|  |                 let code = obj.unicode | |||
|  |                 let result = "case \(name) = 0x\(code)" | |||
|  |                 set.append(result) | |||
|  |             } | |||
|  |              | |||
|  |             let printStr = set.joined(separator: "\n") | |||
|  |             print("\n\(printStr)\n") | |||
|  |         } | |||
|  |      | |||
|  |     private class func iconFont(_ size: CGFloat) -> UIFont? { | |||
|  |         if size == 0.0 { | |||
|  |             return nil | |||
|  |         } | |||
|  |         let iconfont = "iconfont" // 字体的名字 | |||
|  |         loadMyCustomFont(iconfont) | |||
|  |         return UIFont(name: iconfont, size: size) | |||
|  |     } | |||
|  | 
 | |||
|  |     private class func loadMyCustomFont(_ name: String) { | |||
|  |         guard let fontPath = Bundle(for: MWIconFont.self).path(forResource: name, ofType: "ttf") else { | |||
|  |             return | |||
|  |         } | |||
|  |         var error: Unmanaged<CFError>? | |||
|  |         guard let data = try? Data(contentsOf: URL(fileURLWithPath: fontPath)), | |||
|  |               let provider = CGDataProvider(data: data as CFData) | |||
|  |         else { | |||
|  |             return | |||
|  |         } | |||
|  |         if let font = CGFont(provider) { | |||
|  |             CTFontManagerRegisterGraphicsFont(font, &error) | |||
|  |             if error != nil { | |||
|  |                 return | |||
|  |             } | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     /// 将Int类型的转为String类型的Unicode码,eg: 0xe624 -> \u{E624} | |||
|  |     private class func stringForIcon(_ iconInt: UInt32) -> String? { | |||
|  |         var rawIcon = iconInt | |||
|  |         let xPtr = withUnsafeMutablePointer(to: &rawIcon) { $0 } | |||
|  |         return String(bytesNoCopy: xPtr, | |||
|  |                       length: MemoryLayout<UInt32>.size, | |||
|  |                       encoding: String.Encoding.utf32LittleEndian, | |||
|  |                       freeWhenDone: false) | |||
|  |     } | |||
|  | 
 | |||
|  |     /// 生成IconFont | |||
|  |     /// | |||
|  |     /// - Parameters: | |||
|  |     ///   - iconInt: Unicode-Int类型的 eg: 0xe624 | |||
|  |     ///   - size: fontSize | |||
|  |     ///   - color: fontColor | |||
|  |     /// - Returns: font? | |||
|  |     @objc public class func attributedString( | |||
|  |         fromIconInt iconInt: UInt32, | |||
|  |         size: CGFloat, | |||
|  |         color: UIColor?) -> NSAttributedString? | |||
|  |     { | |||
|  |         guard let string = stringForIcon(iconInt) else { | |||
|  |             return nil | |||
|  |         } | |||
|  |         return MWIconFont.attributedString(fromIconStr: string, size: size, color: color) | |||
|  |     } | |||
|  | 
 | |||
|  |     /// 生成IconFont | |||
|  |     /// | |||
|  |     /// - Parameters: | |||
|  |     ///   - iconStr: Unicode-String类型的 eg: "\u{E624}" | |||
|  |     ///   - size: fontSize | |||
|  |     ///   - color: fontColor | |||
|  |     /// - Returns: font? | |||
|  |     @objc public class func attributedString( | |||
|  |         fromIconStr iconStr: String, | |||
|  |         size: CGFloat, | |||
|  |         color: UIColor?) -> NSAttributedString? | |||
|  |     { | |||
|  |         guard let font = MWIconFont.iconFont(size) else { | |||
|  |             return nil | |||
|  |         } | |||
|  |         var attributes = [NSAttributedString.Key: AnyObject]() | |||
|  |         attributes[NSAttributedString.Key.font] = font | |||
|  |         if let color = color { | |||
|  |             attributes[NSAttributedString.Key.foregroundColor] = color | |||
|  |         } | |||
|  |         return NSAttributedString(string: iconStr, attributes: attributes) | |||
|  |     } | |||
|  | 
 | |||
|  |     /// iconfont生成image | |||
|  |     /// | |||
|  |     /// - Parameters: | |||
|  |     ///   - iconInt: Unicode-Int类型的 eg: 0xe624 | |||
|  |     ///   - size: 图片宽高 | |||
|  |     ///   - color: 图片颜色 | |||
|  |     /// - Returns: image? | |||
|  |     @objc public class func image( | |||
|  |         fromIconInt iconInt: UInt32, | |||
|  |         size: CGSize, | |||
|  |         color: UIColor?, | |||
|  |         edgeInsets: UIEdgeInsets = UIEdgeInsets.zero) -> UIImage? | |||
|  |     { | |||
|  |         guard let string = stringForIcon(iconInt) else { | |||
|  |             return nil | |||
|  |         } | |||
|  |         return MWIconFont.image(fromIconStr: string, size: size, color: color, edgeInsets: edgeInsets) | |||
|  |     } | |||
|  |      | |||
|  |     @objc public class func image( | |||
|  |         fromIcon iconEnum: IconCode, | |||
|  |         size: CGSize, | |||
|  |         color: UIColor?, | |||
|  |         edgeInsets: UIEdgeInsets = UIEdgeInsets.zero) -> UIImage? | |||
|  |     { | |||
|  |         guard let string = stringForIcon(iconEnum.rawValue) else { | |||
|  |             return nil | |||
|  |         } | |||
|  |         return MWIconFont.image(fromIconStr: string, size: size, color: color, edgeInsets: edgeInsets) | |||
|  |     } | |||
|  | 
 | |||
|  |     /// iconfont生成image | |||
|  |     /// | |||
|  |     /// - Parameters: | |||
|  |     ///   - iconStr: Unicode-String类型的 eg: "\u{E624}" | |||
|  |     ///   - size: 图片宽高 | |||
|  |     ///   - color: 图片颜色 | |||
|  |     /// - Returns: image? | |||
|  |     private class func image( | |||
|  |         fromIconStr iconStr: String, | |||
|  |         size: CGSize, | |||
|  |         color: UIColor?, | |||
|  |         edgeInsets: UIEdgeInsets = UIEdgeInsets.zero) -> UIImage? | |||
|  |     { | |||
|  |         if size == CGSize.zero { | |||
|  |             return nil | |||
|  |         } | |||
|  |         let pointSize = min(size.width, size.height) | |||
|  |         guard let aString = MWIconFont.attributedString(fromIconStr: iconStr, size: pointSize, color: color) else { | |||
|  |             return nil | |||
|  |         } | |||
|  |         let mString = NSMutableAttributedString(attributedString: aString) | |||
|  | 
 | |||
|  |         var rect = CGRect(origin: CGPoint.zero, size: size) | |||
|  |         rect.origin.y -= edgeInsets.top | |||
|  |         rect.size.width -= edgeInsets.left + edgeInsets.right // 运算符优先级注意 | |||
|  |         rect.size.height -= edgeInsets.top + edgeInsets.bottom | |||
|  | 
 | |||
|  |         let paragraphStyle = NSMutableParagraphStyle() | |||
|  |         paragraphStyle.alignment = .center | |||
|  | 
 | |||
|  |         let range = NSRange(location: 0, length: mString.length) | |||
|  | 
 | |||
|  |         mString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: range) | |||
|  |         // render the attributed string as image using Text Kit | |||
|  |         UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) | |||
|  |         mString.draw(in: rect) | |||
|  |         let image = UIGraphicsGetImageFromCurrentImageContext() | |||
|  |         UIGraphicsEndImageContext() | |||
|  | 
 | |||
|  |         return image | |||
|  |     } | |||
|  | } | |||
|  | 
 | |||
|  | struct IconFontRootModel: Codable { | |||
|  |     let glyphs: [IconFontModel] | |||
|  | } | |||
|  | 
 | |||
|  | struct IconFontModel: Codable { | |||
|  |     let name: String | |||
|  |     let unicode: String | |||
|  | } |