如何在UIViewController与SwiftUI View间共享捕获的图片数据?
解决SwiftUI与UIKit拍照组件的图片传递问题
要把UIKit捕获的图片传到SwiftUI的ContentView,核心是通过Binding + 闭包实现跨框架的数据传递,具体修改如下:
1. 修改ContentView,添加状态变量存储捕获的图片
在ContentView里声明一个@State变量,用来接收从UIKit传来的图片:
import SwiftUI // 补充导入SwiftUI(原代码遗漏) import AVFoundation import UIKit struct ContentView: View { // 新增:存储捕获的图片 @State private var capturedImage: UIImage? var body: some View { ZStack { Color.purple // 将Binding传递给HostedViewController HostedViewController(capturedImage: $capturedImage) .ignoresSafeArea() // 可选:在ContentView中直接展示捕获的图片 if let image = capturedImage { Image(uiImage: image) .resizable() .scaledToFit() .padding() } } } } #Preview { ContentView() }
2. 修改HostedViewController,添加Binding属性
让UIViewControllerRepresentable接收ContentView传来的Binding,同时指定具体的ViewController类型(避免使用基类):
struct HostedViewController: UIViewControllerRepresentable { // 新增:接收ContentView的Binding @Binding var capturedImage: UIImage? func makeUIViewController(context: Context) -> ViewController { let vc = ViewController() // 设置闭包,用于接收ViewController传来的图片 vc.onImageCaptured = { image in self.capturedImage = image } return vc } func updateUIViewController(_ uiViewController: ViewController, context: Context) { } // 修改为具体的ViewController类型 typealias UIViewControllerType = ViewController }
3. 在ViewController里添加闭包,用于传递图片
给ViewController添加一个可选闭包,当捕获到图片时触发它:
class ViewController: UIViewController { // capture session var session: AVCaptureSession? // photo output let output = AVCapturePhotoOutput() // video preview let previewLayer = AVCaptureVideoPreviewLayer() // 新增:闭包,向外部传递图片 var onImageCaptured: ((UIImage) -> Void)? //The rest is a bunch of AVCapture stuff that isn't relevant to my question @objc private func didTapTakePhoto() { output.capturePhoto(with: AVCapturePhotoSettings(), delegate: self) } }
4. 修改photoOutput方法,调用闭包传递图片
在捕获到图片后,调用闭包把图片传给外部,可按需移除UIKit内的图片展示代码:
extension ViewController: AVCapturePhotoCaptureDelegate { func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { guard let data = photo.fileDataRepresentation(), let image = UIImage(data: data) else { return } // 调用闭包,将图片传递给ContentView onImageCaptured?(image) session?.stopRunning() // 可选:若不需要在UIKit界面展示图片,可删除以下代码 // let imageView = UIImageView(image: image) // imageView.contentMode = .scaleAspectFill // imageView.frame = view.bounds // view.addSubview(imageView) } }
修改完成后,拍照捕获的图片会通过闭包和Binding自动同步到ContentView的capturedImage变量中,你可以在SwiftUI视图里自由使用这张图片。
内容的提问来源于stack exchange,提问作者BriteKnight
相关产品推荐
相关产品推荐

