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

SwiftUI中QR码放大模糊及页面跳转延迟问题求助

SwiftUI QR码模糊与页面延迟问题解决

问题1:QR码放大后模糊

CIFilter生成的原始QR码尺寸极小(通常仅几十像素),直接通过resizable()拉伸会导致像素化模糊。正确做法是在生成阶段直接按目标尺寸放大图像,而非事后拉伸。

问题2:页面导航延迟

你的代码存在两个性能隐患:

  • CIContext和CIFilter作为View的实例属性,每次View初始化都会重复创建,这两个对象初始化开销较大
  • generateQRCode方法在body中被调用,而SwiftUI的body会频繁刷新,导致重复生成QR码,占用CPU资源

问题3:关于CIPortraitEffectSpillCorrection日志错误

这是iOS模拟器的已知bug,和你的QR码实现完全无关,真机运行时不会出现该日志,直接忽略即可。


修复后的代码

struct SampleView: View {
    // 目标QR码尺寸
    let qrWidth = UIScreen.main.bounds.width / 2
    
    // 静态属性,避免重复创建开销大的对象
    static let context = CIContext()
    static let filter = CIFilter.qrCodeGenerator()
    
    // 缓存生成好的QR码图片,避免重复计算
    @State private var qrImage: UIImage?
    
    var body: some View {
        VStack(alignment: .leading) { // 修正笔误:stack -> VStack
            if let qrImage = qrImage {
                Image(uiImage: qrImage)
                    .scaledToFit()
                    .frame(width: qrWidth, height: qrWidth)
            } else {
                Text("Error")
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
        .padding()
        .background(Color.white)
        .onAppear {
            // 页面出现时在后台线程生成QR码,避免阻塞主线程
            DispatchQueue.global().async {
                let image = generateQRCode(from: "https://www.hackingwithswift.com/books/ios-swiftui/generating-and-scaling-up-a-qr-code", targetSize: qrWidth)
                DispatchQueue.main.async {
                    qrImage = image
                }
            }
        }
    }
    
    func generateQRCode(from string: String, targetSize: CGFloat) -> UIImage? {
        Self.filter.message = Data(string.utf8)
        
        guard let outputImage = Self.filter.outputImage else {
            return UIImage(systemName: "xmark.circle")
        }
        
        // 计算缩放比例,将原始小图放大到目标尺寸
        let scale = targetSize / outputImage.extent.width
        let scaledImage = outputImage.transformed(by: CGAffineTransform(scaleX: scale, y: scale))
        
        // 生成高清UIImage
        guard let cgImage = Self.context.createCGImage(scaledImage, from: scaledImage.extent) else {
            return UIImage(systemName: "xmark.circle")
        }
        
        return UIImage(cgImage: cgImage)
    }
}

关键优化点:

  • 将CIContext和CIFilter设为静态属性,全局仅初始化一次,大幅降低开销
  • 在onAppear中后台线程生成QR码,避免阻塞主线程导致导航延迟
  • 生成时直接按目标尺寸缩放原始QR码图像,保证高清显示
  • 用@State缓存生成好的图片,避免body刷新时重复计算

内容的提问来源于stack exchange,提问作者BraveEvidence

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 23:25:32