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

SwiftUI拍照后如何跳转至新页面?导航异常问题求助

解决SwiftUI拍摄照片后导航到新页面的问题

你当前的实现是拍摄完成后关闭相机sheet并回到原页面显示照片,这和你想要的「打开新页面展示照片+按钮」的需求不符。我们可以通过调整导航逻辑来实现预期效果,下面是具体的修改方案:

核心思路

  1. 给主页面添加导航栈(NavigationStack,iOS16+推荐使用,如需兼容旧版可替换为NavigationView)。
  2. 新增一个专门展示拍摄结果的详情页面。
  3. 在拍摄完成时,通过闭包通知主页面触发导航,跳转到详情页面。

修改后的完整代码

1. 新增照片详情页面 PhotoDetailView

import SwiftUI

struct PhotoDetailView: View {
    let image: Image
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        VStack {
            // 展示拍摄的照片
            image.resizable()
                .scaledToFit()
            
            // 自定义按钮(这里示例是返回按钮,你可以替换成需求中的按钮)
            Button("返回首页") {
                dismiss()
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(10)
        }
        .navigationTitle("拍摄完成")
        .navigationBarTitleDisplayMode(.inline)
    }
}

#if DEBUG
struct PhotoDetailView_Previews: PreviewProvider {
    static var previews: some View {
        PhotoDetailView(image: Image(systemName: "photo"))
    }
}
#endif

2. 修改 ImagePicker 及 Coordinator 添加完成回调

import Foundation
import SwiftUI

class ImagePickerCoordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    @Binding var isShown: Bool
    @Binding var image: Image?
    private let onCaptureComplete: () -> Void // 新增完成回调闭包
    
    init(isShown: Binding<Bool>, image: Binding<Image?>, onCaptureComplete: @escaping () -> Void) {
        _isShown = isShown
        _image = image
        self.onCaptureComplete = onCaptureComplete
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        guard let uiImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return }
        image = Image(uiImage: uiImage)
        isShown = false
        onCaptureComplete() // 拍摄完成后触发回调
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        isShown = false
    }
}

struct ImagePicker: UIViewControllerRepresentable {
    @Binding var isShown: Bool
    @Binding var image: Image?
    let onCaptureComplete: () -> Void // 新增完成回调闭包
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {}
    
    func makeCoordinator() -> ImagePickerCoordinator {
        ImagePickerCoordinator(isShown: $isShown, image: $image, onCaptureComplete: onCaptureComplete)
    }
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        picker.sourceType = UIImagePickerController.isSourceTypeAvailable(.camera) ? .camera : .photoLibrary
        return picker
    }
}

3. 修改 PhotoCaptureView 传递回调闭包

import SwiftUI

struct PhotoCaptureView: View {
    @Binding var showImagePicker: Bool
    @Binding var image: Image?
    let onCaptureComplete: () -> Void // 新增回调闭包
    
    var body: some View {
        ImagePicker(isShown: $showImagePicker, image: $image, onCaptureComplete: onCaptureComplete)
    }
}

#if DEBUG
struct PhotoCaptureView_Previews: PreviewProvider {
    static var previews: some View {
        PhotoCaptureView(showImagePicker: .constant(false), image: .constant(Image("")), onCaptureComplete: {})
    }
}
#endif

4. 修改 ContentView 添加导航栈和导航逻辑

import SwiftUI

struct ContentView: View {
    @State private var showImagePicker: Bool = false
    @State private var image: Image? = nil
    @State private var isShowingDetail = false // 控制是否跳转到详情页
    
    var body: some View {
        NavigationStack { // 添加导航栈
            VStack {
                Button("Attach the image") {
                    showImagePicker = true
                }
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(10)
            }
            .sheet(isPresented: $showImagePicker) {
                // 传递拍摄完成的回调,触发导航
                PhotoCaptureView(showImagePicker: $showImagePicker, image: $image) {
                    isShowingDetail = true
                }
            }
            // 根据状态跳转到详情页
            .navigationDestination(isPresented: $isShowingDetail) {
                if let capturedImage = image {
                    PhotoDetailView(image: capturedImage)
                }
            }
            .navigationTitle("首页")
        }
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

效果说明

现在当你点击「Attach the image」按钮打开相机,拍摄完成后:

  1. 相机sheet会关闭
  2. 自动导航到新的PhotoDetailView页面,展示拍摄的照片和自定义按钮
  3. 点击详情页的返回按钮可以回到原页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 23:32:38