SwiftUI中像素与点的转换推荐方法及二维码适配问题
SwiftUI中清晰展示二维码并获取屏幕缩放比例
获取屏幕缩放比例
在SwiftUI中,直接通过UIScreen.main.scale就能拿到当前设备的屏幕缩放比例,不需要借助UIView。这个值由系统实时返回,不管未来苹果推出多少倍密度的设备,都能准确获取,完全不用硬编码假设为3。
生成无模糊的二维码
要避免二维码模块出现模糊边界,核心是让每个二维码模块对应整数个物理像素。具体步骤如下:
- 通过GeometryReader拿到SwiftUI布局中的可用显示点尺寸
- 用屏幕缩放比例将显示点转换为物理像素尺寸
- 计算能容纳的最大二维码模块数(取宽高中较小值的整数),再反推回显示点尺寸(确保是缩放比例的整数倍)
- 基于这个尺寸将CIImage转换为CGImage,再用Image组件展示
代码示例
import SwiftUI import CoreImage.CIFilterBuiltins struct QRCodeView: View { let qrString: String private let context = CIContext() var body: some View { GeometryReader { geo in // 获取当前设备的屏幕缩放比例 let scale = UIScreen.main.scale // 将布局可用的显示点尺寸转换为物理像素尺寸 let maxPhysicalSize = CGSize(width: geo.size.width * scale, height: geo.size.height * scale) // 计算最大可容纳的二维码模块数(每个模块对应1个物理像素) let maxModuleCount = Int(min(maxPhysicalSize.width, maxPhysicalSize.height)) // 转换回显示点尺寸,保证是缩放比例的整数倍 let targetSize = CGSize(width: CGFloat(maxModuleCount)/scale, height: CGFloat(maxModuleCount)/scale) if let qrImage = generateQRImage(size: targetSize) { Image(uiImage: qrImage) .resizable() .scaledToFit() .frame(width: targetSize.width, height: targetSize.height) } } } private func generateQRImage(size: CGSize) -> UIImage? { let filter = CIFilter.qrCodeGenerator() filter.message = Data(qrString.utf8) filter.correctionLevel = "H" guard let ciImage = filter.outputImage else { return nil } let scale = UIScreen.main.scale guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else { return nil } // 生成匹配屏幕密度的UIImage let baseImage = UIImage(cgImage: cgImage, scale: scale, orientation: .up) // 按目标尺寸重绘,确保严格匹配布局要求 UIGraphicsBeginImageContextWithOptions(size, false, scale) baseImage.draw(in: CGRect(origin: .zero, size: size)) let scaledImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return scaledImage } } // 使用示例 struct ContentView: View { var body: some View { QRCodeView(qrString: "https://example.com") .padding() .frame(maxWidth: 300, maxHeight: 300) } }
关键说明
UIScreen.main.scale是获取屏幕缩放比例的官方标准方式,完全适配未来新设备- 始终保证二维码的显示点尺寸是缩放比例的整数倍,这样每个模块会对应整数个物理像素,彻底避免模糊边界
- 生成UIImage时指定正确的scale参数,能让系统正确识别图像的像素密度,避免额外缩放
内容的提问来源于stack exchange,提问作者realh
相关产品推荐
相关产品推荐

