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

如何让相机输出与PhotosPicker共用同一绑定变量capturedImage?

解决相机拍摄照片赋值给capturedImage的问题

要让相机拍摄的照片和相册选择的照片逻辑统一——赋值给capturedImage并自动进入编辑视图,只需修改以下几个部分:

1. 更新CameraModel,添加对capturedImage的绑定

修改CameraModel,新增@Binding类型的capturedImage变量,在照片拍摄完成后将图片数据转为UIImage并赋值:

import Foundation
import AVFoundation
import SwiftUI

class CameraModel: NSObject, ObservableObject,AVCapturePhotoCaptureDelegate {
    @Published var isTaken = false
    @Published var session = AVCaptureSession()
    @Published var alert = false
    @Published var output = AVCapturePhotoOutput()
    @Published var preview = AVCaptureVideoPreviewLayer()
    @Published var picData = Data(count: 0)
    // 添加绑定变量,传递拍摄后的图片
    @Binding var capturedImage: UIImage?

    // 修改初始化方法,接收capturedImage绑定
    init(capturedImage: Binding<UIImage?>) {
        self._capturedImage = capturedImage
        super.init()
    }

    // 原有checkPermissions、setupCamera等方法保持不变

    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        if error != nil {
            return
        }

        print("pic taken...")

        guard let imageData = photo.fileDataRepresentation(),
              let uiImage = UIImage(data: imageData) else { return }

        self.picData = imageData
        // 将拍摄后的图片赋值给绑定变量
        self.capturedImage = uiImage
    }
}

2. 修改CustomCameraView,传递capturedImage绑定给CameraModel

调整CustomCameraView的初始化逻辑,将自身的capturedImage绑定传入CameraModel:

import SwiftUI
import PhotosUI

struct CustomCameraView: View {
    @Environment(\.dismiss) private var dismiss
    @Binding var capturedImage: UIImage?
    // 修改CameraModel初始化方式
    @StateObject var camera: CameraModel

    // 添加自定义初始化方法
    init(capturedImage: Binding<UIImage?>) {
        self._capturedImage = capturedImage
        self._camera = StateObject(wrappedValue: CameraModel(capturedImage: capturedImage))
    }

    var body: some View {
        ZStack {
            GeometryReader { proxy in
                CameraView(camera: camera)

                if camera.isTaken == false {
                    VStack (alignment: .leading) {
                        Spacer()
                        HStack {
                            PhotoPicker { result in
                                switch result {
                                case .success(let image):
                                    capturedImage = image
                                case .failure(let error):
                                    print(error)
                                    capturedImage = nil
                                }
                            }
                            Spacer()
                            Button {
                                camera.takePic()
                            } label: {
                                Image(systemName: "circle")
                                    .font(.system(size: 72))
                                    .foregroundColor(.white)
                            }
                            Spacer()
                            Rectangle()
                                .foregroundColor(.clear)
                                .frame(width: 32, height: 28)
                        }
                        .padding()
                    }
                }
            }
            .padding(.horizontal, 4)
            .cornerRadius(6)
            .background(.black)
        }
        .onAppear {
            camera.checkPermissions()
        }
    }
}

3. 清理UploadPostShell中多余的代码

删除UploadPostShell中未使用的CameraModel实例,并简化视图切换逻辑:

import SwiftUI

struct UploadPostShell: View {
    @Environment(\.dismiss) private var dismiss
    @Binding var capturedImage: UIImage?
    @StateObject var viewModel = UploadPostViewModel()
    // 删除多余的CameraModel实例:@StateObject var camera = CameraModel()

    var body: some View {
        VStack {
            // 原有导航栏代码保持不变
            
            // 简化视图切换判断逻辑
            if capturedImage != nil {
                UploadPostView(capturedImage: $capturedImage, viewModel: viewModel)
            } else {
                CustomCameraView(capturedImage: $capturedImage)
            }
            
            // 底部发布按钮代码保持不变...
        }
        .ignoresSafeArea(.keyboard, edges: .bottom)
        .background(.black)
        .onReceive(viewModel.$didUploadPost) { success in
            if success {
                dismiss()
                capturedImage = nil
            }
        }
    }
}

逻辑说明

通过给CameraModel添加@Binding类型的capturedImage,拍摄完成后直接将图片赋值给该变量,就能让UploadPostShell中的capturedImage实时更新。而UploadPostShell会根据capturedImage是否有值自动切换到编辑视图,完全对齐相册选择的流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:07:06