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

在Swift中检测iPhone摄像头,复刻苹果相机变焦按钮实现问询

在Swift中复刻苹果相机变焦按钮的实用方案

核心思路:依托AVCaptureDevice原生属性获取物理变焦倍率

苹果相机的固定变焦按钮(0.5x/1x/2x/3x/5x等)对应物理摄像头的原生变焦能力,无需硬编码机型适配,直接通过AVCaptureDevice的内置属性就能精准获取这些信息。

1. 筛选可用物理摄像头

先过滤出支持视频拍摄的实体摄像头(排除系统虚拟设备):

import AVFoundation

func getPhysicalCameraDevices() -> [AVCaptureDevice] {
    let discoverySession = AVCaptureDevice.DiscoverySession(
        deviceTypes: [.builtInUltraWideCamera, .builtInWideAngleCamera, .builtInTelephotoCamera],
        mediaType: .video,
        position: .unspecified
    )
    return discoverySession.devices.filter { !$0.isVirtualDevice }
}

2. 计算各摄像头对应的变焦倍率

以广角摄像头(1x基准)的视场角(FOV)为参照,通过对比其他摄像头的FOV算出对应变焦倍率:

func getCameraZoomFactors() -> [CGFloat] {
    let devices = getPhysicalCameraDevices()
    guard let wideAngleDevice = devices.first(where: { $0.deviceType == .builtInWideAngleCamera }) else {
        return [1.0]
    }
    let wideFOV = wideAngleDevice.activeFormat.videoFieldOfView
    
    var zoomFactors = Set<CGFloat>()
    zoomFactors.insert(1.0) // 广角默认1x
    
    for device in devices {
        let fov = device.activeFormat.videoFieldOfView
        // 变焦倍率 = 广角FOV / 当前摄像头FOV(苹果官方近似逻辑)
        let zoomFactor = wideFOV / fov
        // 四舍五入到一位小数,匹配苹果的显示规则
        let roundedFactor = round(zoomFactor * 10) / 10
        zoomFactors.insert(roundedFactor)
    }
    
    // 排序后返回,比如[0.5, 1.0, 2.0, 3.0]或[0.5,1.0,5.0]
    return zoomFactors.sorted()
}

3. 实现变焦按钮的切换逻辑

点击按钮时优先切换到对应物理摄像头,无对应物理镜头时再启用数字变焦:

func switchCamera(toZoomFactor zoomFactor: CGFloat, session: AVCaptureSession) {
    let devices = getPhysicalCameraDevices()
    guard let wideAngleDevice = devices.first(where: { $0.deviceType == .builtInWideAngleCamera }) else {
        return
    }
    let wideFOV = wideAngleDevice.activeFormat.videoFieldOfView
    
    // 寻找对应物理摄像头
    if let targetDevice = devices.first(where: {
        let fov = $0.activeFormat.videoFieldOfView
        let calculatedZoom = round((wideFOV / fov) * 10) / 10
        return calculatedZoom == zoomFactor
    }) {
        // 切换物理摄像头输入
        session.beginConfiguration()
        session.inputs.forEach { session.removeInput($0) }
        if let input = try? AVCaptureDeviceInput(device: targetDevice), session.canAddInput(input) {
            session.addInput(input)
        }
        session.commitConfiguration()
    } else {
        // 无物理镜头时启用数字变焦
        guard let currentInput = session.inputs.first as? AVCaptureDeviceInput,
              let device = currentInput.device,
              device.maxAvailableVideoZoomFactor >= zoomFactor else {
            return
        }
        try? device.lockForConfiguration()
        device.videoZoomFactor = zoomFactor
        device.unlockForConfiguration()
    }
}

关键注意事项

  • 拒绝硬编码机型:不同iPhone的摄像头配置差异(如15 Pro Max的5x长焦),通过FOV计算能自动识别,无需针对机型写判断逻辑
  • 区分物理/数字变焦:苹果相机的固定倍率按钮均对应物理变焦,仅滑动区间为数字变焦,优先切换物理镜头更贴合原生体验
  • 权限前置:务必在Info.plist中添加NSCameraUsageDescription权限申请

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:32:25