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

SwiftUI中像素与点的转换推荐方法及二维码适配问题

SwiftUI中清晰展示二维码并获取屏幕缩放比例

获取屏幕缩放比例

在SwiftUI中,直接通过UIScreen.main.scale就能拿到当前设备的屏幕缩放比例,不需要借助UIView。这个值由系统实时返回,不管未来苹果推出多少倍密度的设备,都能准确获取,完全不用硬编码假设为3。

生成无模糊的二维码

要避免二维码模块出现模糊边界,核心是让每个二维码模块对应整数个物理像素。具体步骤如下:

  1. 通过GeometryReader拿到SwiftUI布局中的可用显示点尺寸
  2. 用屏幕缩放比例将显示点转换为物理像素尺寸
  3. 计算能容纳的最大二维码模块数(取宽高中较小值的整数),再反推回显示点尺寸(确保是缩放比例的整数倍)
  4. 基于这个尺寸将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 21:35:17