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

SwiftUI新PhotosPicker能否直接打开相机而非照片库?

SwiftUI中让选择器直接打开相机的方案

SwiftUI自带的PhotosPicker确实只能默认打开照片库,没有直接跳转相机的参数配置。要实现直接打开相机的需求,你需要基于UIKit的UIImagePickerController封装一个SwiftUI可用的组件,具体步骤如下:

1. 封装相机选择器组件

创建一个遵循UIViewControllerRepresentable的结构体,用来包装UIImagePickerController并设置其sourceType为.camera:

import SwiftUI
import UIKit

struct CameraPicker: UIViewControllerRepresentable {
    @Binding var imageSelection: PhotosPickerItem?
    @Binding var dataImage: Data?
    @Environment(\.dismiss) private var dismiss
    
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.sourceType = .camera
        picker.delegate = context.coordinator
        return picker
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        let parent: CameraPicker
        
        init(_ parent: CameraPicker) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let image = info[.originalImage] as? UIImage {
                // 将拍摄的图片转为Data
                parent.dataImage = image.jpegData(compressionQuality: 0.8)
                // 可选:转为PhotosPickerItem(如果需要和原逻辑兼容)
                if let imageURL = info[.imageURL] as? URL {
                    parent.imageSelection = PhotosPickerItem(url: imageURL)
                }
            }
            parent.dismiss()
        }
        
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            parent.dismiss()
        }
    }
}

2. 替换原代码中的PhotosPicker

把你原来的PhotosPicker替换成上面的CameraPicker,同时别忘了在Info.plist中添加相机权限描述:

  • 添加NSCameraUsageDescription键,值填你需要向用户说明的相机使用理由(比如"需要访问相机拍摄头像")

修改后的代码示例:

// 先在视图里添加状态变量控制相机选择器的显示
@State private var showCameraPicker = false

ImagePikerCircular(im: im, dataImage: $dataImage)
    .overlay(alignment: .bottomTrailing) {
        Button {
            showCameraPicker = true
        } label: {
            Image(systemName: "pencil.circle.fill")
                .symbolRenderingMode(.multicolor)
                .font(.system(size: 30))
                .foregroundColor(.accentColor)
        }
        .buttonStyle(.borderless)
        .sheet(isPresented: $showCameraPicker) {
            CameraPicker(imageSelection: $im.imageSelection, dataImage: $dataImage)
        }
    }

补充说明

  • 如果需要同时支持"打开相机"和"打开照片库"的选项,可以做一个弹窗让用户选择,分别触发CameraPicker和原来的PhotosPicker
  • 相机权限必须提前配置,否则App会崩溃
  • 若你的ImagePikerCircular依赖PhotosPickerItem,上面的代码里已经处理了将拍摄图片转为PhotosPickerItem的逻辑,确保和原有逻辑兼容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:32:39