前提・実現したいこと
下記のようなTableViewを作成しています
表示上はセルを追加されたように見えてもindexPathが増加していないため
didSelectRowAtのindexPathは常に一番目のデータが帰ってきます
どこがいけないんでしょうか?
発生している問題・エラーメッセージ
セルをタップしても、該当のIndexPathが取得できない
該当のソースコード
Swift
1import UIKit 2import AVFoundation 3import AudioToolbox 4 5class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate,UITableViewDelegate,UITableViewDataSource{ 6 7 8 //var itemTable: UITableView? 9 var captureDevice:AVCaptureDevice? 10 var videoPreviewLayer:AVCaptureVideoPreviewLayer? 11 var captureSession:AVCaptureSession? 12 let detectionArea = UIView() 13 var timer: Timer! 14 var counter = 0 15 var tableView: UITableView! 16 //let items = ["Apple","Banana","Orange"] 17 //var barcodeList = [String]() 18 var items = [Item!]() 19 var item: Item! = Item() 20 21 22 override func viewDidLoad() { 23 super.viewDidLoad() 24 25 print("viewDidLoad...") 26 // Do any additional setup after loading the view, typically from a nib. 27 navigationItem.title = "Scanner" 28 view.backgroundColor = .white 29 30 captureDevice = AVCaptureDevice.default(for: .video) 31 // カメラがあるか確認し,取得する 32 if let captureDevice = captureDevice { 33 34 do { 35 let input = try AVCaptureDeviceInput(device: captureDevice) 36 37 captureSession = AVCaptureSession() 38 guard let captureSession = captureSession else { return } 39 captureSession.addInput(input) 40 41 // metadata取得に必要な初期設定 42 let captureMetadataOutput = AVCaptureMetadataOutput() 43 captureSession.addOutput(captureMetadataOutput) 44 45 captureMetadataOutput.setMetadataObjectsDelegate(self, queue: .main) 46 captureMetadataOutput.metadataObjectTypes = [.code128, .qr, .ean13, .ean8, .code39] //AVMetadataObject.ObjectType 47 48 captureSession.startRunning() 49 50 // カメラからの取得映像を画面に表示する 51 videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 52 videoPreviewLayer?.videoGravity = .resizeAspectFill 53 //videoPreviewLayer?.frame = view.layer.bounds 54 videoPreviewLayer?.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height / 4) 55 view.layer.addSublayer(videoPreviewLayer!) 56 57 } catch { 58 print("Error Device Input") 59 } 60 } //end if let 61 62 view.addSubview(codeLabel) 63 codeLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 64 codeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 65 codeLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true 66 codeLabel.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true 67 68 // どの範囲を解析するか設定する 69 let x: CGFloat = 0.05 70 let y: CGFloat = 0.45 71 let width: CGFloat = 0.9 72 let height: CGFloat = 0.1 73 74 //detectionArea.frame = CGRect(x: view.frame.size.width * x, y: view.frame.size.height * y, width: view.frame.size.width * width, height: view.frame.size.height * height) 75 detectionArea.frame = CGRect(x: (videoPreviewLayer?.frame.width)! * x, y: (videoPreviewLayer?.frame.height)! * y, width: view.frame.size.width * width, height: view.frame.size.height * height) 76 detectionArea.layer.borderColor = UIColor.red.cgColor 77 detectionArea.layer.borderWidth = 3 78 view.addSubview(detectionArea) 79 80 timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.update), userInfo: nil, repeats: true) 81 timer.fire() 82 //self.tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "customCell") 83 self.tableView = { [weak self] in 84 guard let `self` = self else { return UITableView() } 85 //let tableView = UITableView(frame: self.view.bounds, style: .plain) 86 let tableView = UITableView(frame: CGRect(x: 0, y: (videoPreviewLayer?.frame.height)!, width: view.frame.size.width, height: view.frame.size.height - (videoPreviewLayer?.frame.height)!), style: .plain); 87 tableView.autoresizingMask = [ 88 .flexibleWidth, 89 .flexibleHeight 90 ] 91 tableView.delegate = self 92 tableView.dataSource = self 93 94 self.view.addSubview(tableView) 95 96 return tableView 97 }() 98 99 } // end viewDidLoad 100 101 override func didReceiveMemoryWarning() { 102 super.didReceiveMemoryWarning() 103 // Dispose of any resources that can be recreated. 104 } 105 106 override func viewWillAppear(_ animated: Bool) { 107 self.tableView.reloadData() 108 } 109 110 func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { 111 if metadataObjects.count == 0 { 112 //print("No Input Detected") 113 codeFrame.frame = CGRect.zero 114 codeLabel.text = "No Data" 115 return 116 } 117 print("call metadataOutput") 118 let metadataObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject 119 120 guard let stringCodeValue = metadataObject.stringValue else { return } 121 counter = 0 122 123 self.item?.title = stringCodeValue 124 self.item?.qty = 1 125 print(self.item!.title as Any) 126 print(self.item!.qty as Any) 127 self.items.append(self.item) 128 129 self.tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: UITableViewRowAnimation.right) 130 131 guard let barcodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObject) else { return } 132 133 // Play system sound with custom mp3 file 134 if let customSoundUrl = Bundle.main.url(forResource: "beep-07", withExtension: "mp3") { 135 var customSoundId: SystemSoundID = 0 136 AudioServicesCreateSystemSoundID(customSoundUrl as CFURL, &customSoundId) 137 //let systemSoundId: SystemSoundID = 1016 // to play apple's built in sound, no need for upper 3 lines 138 139 AudioServicesAddSystemSoundCompletion(customSoundId, nil, nil, { (customSoundId, _) -> Void in 140 AudioServicesDisposeSystemSoundID(customSoundId) 141 }, nil) 142 143 AudioServicesPlaySystemSound(customSoundId) 144 //captureSession?.stopRunning() 145 } 146 147 // Stop capturing and hence stop executing metadataOutput function over and over again 148 print("stop Running") 149 captureSession?.stopRunning() 150 151 // Call the function which performs navigation and pass the code string value we just detected 152 //displayDetailsViewController(scannedCode: stringCodeValue) 153 } 154 155 @objc func update(tm: Timer) { 156 counter += 1 157 //print(counter) 158 if 1 < counter { 159 captureSession?.startRunning() 160 detectionArea.layer.borderColor = UIColor.red.cgColor 161 detectionArea.layer.borderWidth = 3 162 codeLabel.text = "" 163 } 164 } 165 166 func numberOfSections(in tableView: UITableView) -> Int { 167 print("call numberOfSections") 168 return 1 169 } 170 171 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 172 print("items.count (self.items.count)") 173 return self.items.count 174 } 175 176 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 177 178 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") 179 ?? UITableViewCell(style: .default, reuseIdentifier: "Cell") 180 181 cell.textLabel?.text = self.items[indexPath.row].title 182 183 print("call cellForRowAt") 184 return cell 185 186 } 187 188 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 189 190 print("Selected! (self.items[indexPath.row].title)") 191 print("indexPath (self.items[indexPath.row])") 192 193 } 194 195 func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 196 return true 197 } 198 199 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexpath: IndexPath) { 200 if editingStyle == UITableViewCellEditingStyle.delete { 201 //リストから削除 202 items.remove(at: indexpath.row) 203 204 //セルを削除 205 tableView.deleteRows(at: [indexpath], with: UITableViewRowAnimation.fade) 206 } 207 } 208}
質問するときのヒント(https://teratail.com/help/question-tips)を読んで、ソースコードにシンタックスハイライトを付けてください。ソースが読みづらくて回答が得られにくいと思います。
回答3件
あなたの回答
tips
プレビュー