大家好,我正在编写一个反应原生项目。我需要在我的 react native 项目中使用 IOS Vision Kit。我找到了一个用于视觉套件的 swift 项目,它在 swift 上运行得非常好。我正在尝试将其作为本机模块连接。我找到了一些可以称为原生 swift 代码的东西。那只是显示标签文本。然后我把为视觉套件编写的 swift 代码放在视图中,而不是这个标签文本,但现在它什么都不显示。
let screen = RCTDocumentContentView()
let viewScreen = UIHostingController(rootView: screen)
self.addSubview(viewScreen.view)
这部分是为此完成的。您可以在下面查看所有代码。首先,我不知道我是否可以将此视觉套件项目称为 react-native 中的视图。当我们将其称为视图时,它是否在 react-native 项目中工作?我不确定如何正确调用此代码以做出本机反应。有人帮我找到解决方法吗?
这是我的 RTCDocument.m 文件:
#import "React/RCTBridgeModule.h"
#import "React/RCTViewManager.h"
@interface RCT_EXTERN_MODULE(SampleViewManager, RCTViewManager)
@end
这是我的 SampleView.swift 文件:
import Foundation
import SwiftUI
import UIKit
class SampleView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100,
height: 50))
label.text = "This is Swift"
let screen = RCTDocumentContentView()
let viewScreen = UIHostingController(rootView: screen)
self.addSubview(viewScreen.view)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
这是我的 RCTDocumentContentView.swift 文件:
import SwiftUI
struct RCTDocumentContentView: View {
@State private var showScannerSheet = false
@State private var texts:[RCTDocumentScanData] = []
var body: some View {
NavigationView{
VStack{
if texts.count > 0 {
List{
ForEach(texts){
text in NavigationLink(
destination:ScrollView{Text(text.content)},
label:{
Text(text.content).lineLimit(1)
}
)
}
}
}
else{
Text("No scan yet").font(.title)
}
}
.navigationTitle("Alper Rocks")
.navigationBarItems(
trailing: Button(action:{
self.showScannerSheet = true
}, label:{
Image(systemName:"doc.text.viewfinder").font(.title)
}).sheet(isPresented: $showScannerSheet, content: {
makeScannerView()
})
)
}
}
private func makeScannerView() -> RCTDocumentScannerView{
RCTDocumentScannerView(completion: {
textPerPage in
if let outputText = textPerPage?.joined(separator: "\n")
.trimmingCharacters(in:.whitespacesAndNewlines){
let newScanData = RCTDocumentScanData(content: outputText)
self.texts.append(newScanData)
}
self.showScannerSheet = false
})
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
RCTDocumentContentView()
}
}
这是我的 RCTDocumentScannerView.swift 文件:
import VisionKit
import SwiftUI
struct RCTDocumentScannerView: UIViewControllerRepresentable{
func updateUIViewController(_ uiViewController: VNDocumentCameraViewController, context: Context) {}
private let completionHandler: ([String]?) -> Void
init(completion: @escaping ([String]?) -> Void){
self.completionHandler = completion
}
typealias UIViewControllerRepresentableType = VNDocumentCameraViewController
func makeUIViewController(context: UIViewControllerRepresentableContext<RCTDocumentScannerView>) -> VNDocumentCameraViewController {
let viewController = VNDocumentCameraViewController()
viewController.delegate = context.coordinator
return viewController
}
func makeCoordinator() -> Coordinator {
return Coordinator(completion: completionHandler)
}
final class Coordinator: NSObject, VNDocumentCameraViewControllerDelegate{
private let completionHandler: ([String]?) -> Void
init(completion: @escaping ([String]?) -> Void){
self.completionHandler = completion
}
func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
let recognizer = RCTDocumentTextRecognizer(cameraScan: scan)
recognizer.recognizeText(withCompletionHandler: completionHandler)
}
func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
completionHandler(nil)
}
func documentCameraViewControllerDidCancel(_ controller:VNDocumentCameraViewController){
completionHandler(nil)
}
}
}
这是我的 RCTDocumentScanData.swift 文件:
import Foundation
import SwiftUI
struct RCTDocumentScanData:Identifiable {
var id = UUID()
let content:String
init(content:String) {
self.content = content
}
}
这是我的 RCTDocumentTextRecognizer.swift 文件:
import Foundation
import Vision
import VisionKit
final class RCTDocumentTextRecognizer{
let cameraScan: VNDocumentCameraScan
init(cameraScan:VNDocumentCameraScan){
self.cameraScan = cameraScan
}
private let queue = DispatchQueue(label: "scan-codes",qos: .default,attributes:[],autoreleaseFrequency: .workItem)
func recognizeText(withCompletionHandler completionHandler: @escaping ([String]) -> Void){
queue.async {
let images = (0..<self.cameraScan.pageCount).compactMap({
self.cameraScan.imageOfPage(at: $0).cgImage
})
let imagesAndRequests = images.map({(image: $0, request: VNRecognizeTextRequest())})
let textPerPage = imagesAndRequests.map{image,request -> String in
let handler = VNImageRequestHandler(cgImage: image, options: [:])
do{
try handler.perform([request])
guard let observations = request.results as? [VNRecognizedTextObservation] else {return ""}
return observations.compactMap({$0.topCandidates(1).first?.string}).joined(separator: "\n")
}
catch{
print(error)
return ""
}
}
DispatchQueue.main.async {
completionHandler(textPerPage)
}
}
}
}
这是我的头文件:
#import "React/RCTBridgeModule.h"
#import "React/RCTViewManager.h"
This is my SampleView.ios.js file :
import { requireNativeComponent } from 'react-native';
// requireNativeComponent automatically resolves this to "SampleViewManager"
module.exports = requireNativeComponent('SampleView', null);
这就是我在 App.js 中的称呼
const SampleView = require('./SampleView.ios.js');
<SampleView style={{
flex:1,width:"100%",height:"100%",
margin: 10,
borderWidth: 1,
}} />