実現したいこと
「Cannot find 'ContentView' in scope」を解決する
前提
本をカメラに映して、タップした本のタイトルを表示するようにしたいです。
発生している問題・エラーメッセージ
cannot find 'contentview' in scope
該当のソースコード
swift
1//App.swift 2 3import SwiftUI 4 5@main 6struct App: App { 7 var body: some Scence { 8 WindowGroup { 9 ContentView() //<-- Cannot find 'ContentView' in scope 10 } 11 } 12}
swift
1//ContentView.swift 2 3import UIKit 4import AVFoundation 5import Vision 6 7struct CGRectWrapper: Hashable { 8 let rect: CGRect 9 10 func hash(into hasher: inout Hasher) { 11 hasher.combine(rect.origin.x) 12 hasher.combine(rect.origin.y) 13 hasher.combine(rect.size.width) 14 hasher.combine(rect.size.height) 15 } 16} 17 18class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate { 19 let captureSession = AVCaptureSession() 20 let titleLabel = UILabel() 21 22 var recognizedBooks: [CGRectWrapper: String] = [:] 23 24 override func viewDidLoad() { 25 super.viewDidLoad() 26 27 titleLabel.textAlignment = .center 28 titleLabel.textColor = .white 29 titleLabel.backgroundColor = .black 30 titleLabel.alpha = 0.8 31 titleLabel.numberOfLines = 2 32 titleLabel.font = UIFont.boldSystemFont(ofSize: 16) 33 titleLabel.translatesAutoresizingMaskIntoConstraints = false 34 view.addSubview(titleLabel) 35 36 let padding: CGFloat = 16 37 NSLayoutConstraint.activate([ 38 titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding), 39 titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding), 40 titleLabel.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -padding), 41 ]) 42 43 guard let videoDevice = AVCaptureDevice.default(for: .video) else { 44 fatalError("ビデオデバイスが利用できません") 45 } 46 47 do { 48 let videoInput = try AVCaptureDeviceInput(device: videoDevice) 49 50 if captureSession.canAddInput(videoInput) { 51 captureSession.addInput(videoInput) 52 } else { 53 fatalError("入力をセッションに追加できません") 54 } 55 } catch { 56 fatalError("ビデオ入力の作成に失敗しました: \(error)") 57 } 58 59 let videoOutput = AVCaptureVideoDataOutput() 60 videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: .userInteractive)) 61 62 if captureSession.canAddOutput(videoOutput) { 63 captureSession.addOutput(videoOutput) 64 } else { 65 fatalError("出力をセッションに追加できません") 66 } 67 68 captureSession.startRunning() 69 } 70 71 func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { 72 guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { 73 return 74 } 75 76 let ciImage = CIImage(cvImageBuffer: imageBuffer) 77 let options: [VNImageOption: Any] = [:] 78 let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage, orientation: .up, options: options) 79 80 let textRecognitionRequest = VNRecognizeTextRequest { request, error in 81 if let error = error { 82 print("文字認識エラー: \(error)") 83 return 84 } 85 86 guard let results = request.results as? [VNRecognizedTextObservation], !results.isEmpty else { 87 return 88 } 89 90 self.recognizedBooks = [:] // 認識結果をリセット 91 92 for result in results { 93 guard let candidate = result.topCandidates(1).first else { 94 continue 95 } 96 97 let boundingBox = result.boundingBox 98 let transformedBoundingBox = self.transformBoundingBox(boundingBox) 99 100 // 画面上に枠線を描画 101 DispatchQueue.main.async { 102 self.drawBoundingBox(transformedBoundingBox) 103 } 104 105 // 認識結果を辞書に保存 106 self.recognizedBooks[CGRectWrapper(rect: transformedBoundingBox)] = candidate.string 107 } 108 } 109 textRecognitionRequest.recognitionLevel = .accurate 110 111 do { 112 try imageRequestHandler.perform([textRecognitionRequest]) 113 } catch { 114 print("文字認識リクエストエラー: \(error)") 115 } 116 } 117 118 func transformBoundingBox(_ boundingBox: CGRect) -> CGRect { 119 // Visionフレームワークの座標系からUIKitの座標系に変換 120 let transformedRect = VNImageRectForNormalizedRect(boundingBox, Int(view.bounds.width), Int(view.bounds.height)) 121 122 // 鏡像反転 123 let flipTransform = CGAffineTransform(scaleX: -1, y: -1).translatedBy(x: -view.bounds.width, y: -view.bounds.height) 124 let flippedRect = transformedRect.applying(flipTransform) 125 126 return flippedRect 127 } 128 129 func drawBoundingBox(_ boundingBox: CGRect) { 130 let boundingBoxLayer = CALayer() 131 boundingBoxLayer.frame = boundingBox 132 boundingBoxLayer.borderColor = UIColor.red.cgColor 133 boundingBoxLayer.borderWidth = 2 134 view.layer.addSublayer(boundingBoxLayer) 135 } 136 137 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 138 guard let touch = touches.first else { 139 return 140 } 141 142 let touchPoint = touch.location(in: view) 143 144 // タップした点がどの枠線内にあるかを判定 145 if let selectedBook = recognizedBooks.first(where: { $0.key.rect.contains(touchPoint) }) { 146 let selectedTitle = selectedBook.value 147 titleLabel.text = selectedTitle 148 } 149 } 150} 151
試したこと
- 新しくプロジェクトを作成し、ビルドする
- Build PhasesのCompile Sourceを確認し、ContentView.swiftが含まれていることを確認する
- xcodeの再起動
補足情報(FW/ツールのバージョンなど)
xcode 14.3
回答1件
あなたの回答
tips
プレビュー