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
相关产品推荐
相关产品推荐

