You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 12:59:14