Swift中自定义锁屏通知:实现Telegram式联系人首字母图标替换
在Swift中实现锁屏通知显示联系人首字母图标
一、生成带首字母的圆形头像图片
先实现一个工具函数,输入联系人姓名后生成带首字母的圆形图片,背景色可以通过姓名哈希值生成差异化颜色,保证不同联系人的图标区分度:
func generateInitialsImage(name: String, size: CGSize = CGSize(width: 60, height: 60)) -> UIImage? { let renderer = UIGraphicsImageRenderer(size: size) return renderer.image { context in // 基于姓名哈希生成背景色 let hash = name.hashValue let hue = CGFloat((hash % 360 + 360) % 360) / 360.0 let color = UIColor(hue: hue, saturation: 0.7, brightness: 0.9, alpha: 1.0) color.setFill() // 绘制圆形背景 let rect = CGRect(origin: .zero, size: size) UIBezierPath(ovalIn: rect).fill() // 提取并绘制首字母(最多取前两个) let initials = name.components(separatedBy: " ") .compactMap { $0.first?.uppercased() } .joined() .prefix(2) let text = String(initials) let attributes: [NSAttributedString.Key: Any] = [ .font: UIFont.systemFont(ofSize: size.width * 0.4, weight: .bold), .foregroundColor: UIColor.white ] let textSize = text.size(withAttributes: attributes) let textRect = CGRect( x: (size.width - textSize.width) / 2, y: (size.height - textSize.height) / 2, width: textSize.width, height: textSize.height ) text.draw(in: textRect, withAttributes: attributes) } }
二、将图片转换为通知附件
系统通知的自定义图标需要以UNNotificationAttachment形式添加,而附件要求本地文件URL,因此需要把生成的图片保存到临时目录:
func createNotificationAttachment(from image: UIImage) throws -> UNNotificationAttachment { let tempDir = FileManager.default.temporaryDirectory let fileName = UUID().uuidString + ".png" let fileURL = tempDir.appendingPathComponent(fileName) guard let imageData = image.pngData() else { throw NSError(domain: "InitialsImageError", code: 0, userInfo: [NSLocalizedDescriptionKey: "图片转数据失败"]) } try imageData.write(to: fileURL) return try UNNotificationAttachment(identifier: "initials_attachment", url: fileURL, options: [UNNotificationAttachmentOptionsThumbnailHiddenKey: false]) }
三、发送带自定义图标的通知
在构建通知内容时,将生成的附件加入,系统会自动在锁屏通知中用该附件替换默认应用图标:
func sendInitialsNotification(name: String, title: String, body: String) { // 生成首字母图片 guard let initialsImage = generateInitialsImage(name: name) else { print("生成首字母图片失败") return } // 创建通知附件 guard let attachment = try? createNotificationAttachment(from: initialsImage) else { print("创建通知附件失败") return } // 配置通知内容 let content = UNMutableNotificationContent() content.title = title content.body = body content.attachments = [attachment] // 创建并发送通知请求 let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) UNUserNotificationCenter.current().add(request) { error in if let error = error { print("发送通知失败: \(error.localizedDescription)") } } }
四、前置准备
确保已在App启动时请求通知权限:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { granted, _ in if granted { application.registerForRemoteNotifications() } } return true }
内容的提问来源于stack exchange,提问作者PDord
相关产品推荐
相关产品推荐

