首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将VNDocumentCameraViewController用作TabView中的UIViewControllerRepresentable

将VNDocumentCameraViewController用作TabView中的UIViewControllerRepresentable
EN

Stack Overflow用户
提问于 2021-08-17 06:11:07
回答 2查看 456关注 0票数 1

我将VNDocumentCameraViewController作为一个UIViewControllerRepresentable,在一个名为ScanView的视图中嵌入TabView作为第二个屏幕。在取消VNDocumentCameraViewController (取消扫描或保存扫描)时,我希望选项卡视图返回到我的第一个屏幕。那部分就像一种魅力。

不过,我的问题是,当回到我的VNDocumentCameraViewController时,我想恢复控制器并重新开始--这就是我想不出如何实现它的原因。

我知道,我的ContentView保持对ScanView的引用是为什么我的UIViewControllerRepresentable没有恢复-我如何能够手动做到这一点?

下面是代码:

代码语言:javascript
复制
import SwiftUI

@main
struct so_VisionKitInTabsApp: App {
        var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State private var tabSelection = 1

    var body: some View {
        TabView(selection: $tabSelection) {
            Text("First View")
                .tabItem { Text("First View") }
                .tag(1)
            ScanView(tabSelection: $tabSelection)
                .tabItem { Text("Scan View") }
                .tag(2)
        }
    }
}

import VisionKit

struct DocumentScanningViewAdapter: UIViewControllerRepresentable {
    typealias UIViewControllerType = VNDocumentCameraViewController

    let onDismiss: () -> ()
        
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }

    func makeUIViewController(context: Context) -> VNDocumentCameraViewController {
        let vc = VNDocumentCameraViewController()
        vc.delegate = context.coordinator
        return vc
    }
    
    func updateUIViewController(_ uiViewController: VNDocumentCameraViewController, context: Context) { }

    class Coordinator: NSObject, VNDocumentCameraViewControllerDelegate {
        var parent: DocumentScanningViewAdapter
        
        init(parent: DocumentScanningViewAdapter) {
            self.parent = parent
        }
        
        func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
            print("Finished successfully…")
            parent.onDismiss()
        }
        
        func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
            print("Cancelled…")
            resetCoordinator(for: controller)
            parent.onDismiss()
        }
        
        func resetCoordinator(for controller: VNDocumentCameraViewController) {
            controller.delegate = parent.makeCoordinator()
        }
    }
    
}

struct ScanView: View {
    @Binding var tabSelection: Int
    
    var body: some View {
        DocumentScanningViewAdapter(onDismiss: { tabSelection = 1 })
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-17 06:33:13

这是TabView的工作方式:它保存每个选项卡的状态

您本可以破解它,但请不要:当iOS用户看到选项卡视图时,他希望如果从一个选项卡切换到另一个选项卡,他不会丢失任何状态。

相反,只需制作一个按钮,将您的文档选择器显示为.sheet(...),或者使用NavigationLink在导航控制器中推送,您的问题就会消失。

如果使用这种方法之一,就不需要重置控制器的状态,因为每次呈现视图时都会重新创建它

如果您还想这样做,您可以用UINavigationController包装控制器,并在updateUIViewController中初始化您自己的控制器。

代码语言:javascript
复制
func makeUIViewController(context: Context) -> UINavigationController {
    let controller = UINavigationController()
    controller.isNavigationBarHidden = true
    return controller
}

func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {
    let vc = VNDocumentCameraViewController()
    vc.delegate = context.coordinator
    uiViewController.viewControllers = [vc]
}

每次需要重新呈现视图时,都会调用updateUIViewController。如果使用TabView,它仍然无法工作,因为状态是保存的,因此可以将.id(tabSelection)添加到ScanView

票数 2
EN

Stack Overflow用户

发布于 2021-08-17 07:33:30

由于菲利普上面的回答,建议我可以使用.sheet,我想出了一个新的ScanView,它使用.fullScreenCover

做这项工作,但它将覆盖标签栏(我认为我可以接受)。

代码语言:javascript
复制
struct ScanView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    @State private var showFullscreen = true
    @Binding var tabSelection: Int
    
    var body: some View {
        EmptyView()
            .fullScreenCover(isPresented: $showFullscreen, onDismiss: {
                presentationMode.wrappedValue.dismiss()
            }) {
                DocumentScanningViewAdapter(onDismiss: {
                    showFullscreen = false
                    tabSelection = 1
                })
            }
            .onAppear {
                showFullscreen = true
            }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68812427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档