質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

3回答

971閲覧

複数のVC間でのデータの受け渡し方法が知りたい

Haruto513

総合スコア52

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2019/06/03 20:56

前提・実現したいこと

Swiftまだ素人です。
端末のカメラを使って商品のバーコードを読み取り、それを使って色々するアプリを制作しています。
異なる複数のViewControllerに置かれたボタンから、ReaderVCという共通のカメラを起動しバーコードを読み取ると、元の画面に戻り、画面に置かれたTextFieldの中に入力されるという処理を実現したいのですが、どんなやり方をすれば実現できるのか目処が立っていない状況です。
ユーザーデフォルトは使わないという条件なので、NotificationCenterやクロージャーを使って処理するという案も出ているのですが、どちらも使い方を理解するのが難しいです。
VC間のデータの受け渡しには、他にもやり方はあるのでしょうか。

参考になるWebページのリンクやヒントになるようなことを知っていらしたら教えてくださると嬉しいです。

イメージ説明
それぞれの画面にViewControllerのファイルがあります。

該当のソースコード

ReaderVC

1 2import UIKit 3import AVFoundation 4 5class ReaderVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 6 7 private let session = AVCaptureSession() 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 12 let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: .back) 13 let devices = discoverySession.devices 14 if let backCamera = devices.first{ 15 do{ 16 let deviceInput = try AVCaptureDeviceInput(device: backCamera) 17 if self.session.canAddInput(deviceInput){ 18 self.session.addInput(deviceInput) 19 let metadataOutput = AVCaptureMetadataOutput() 20 if self.session.canAddOutput(metadataOutput){ 21 self.session.addOutput(metadataOutput) 22 metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) 23 24 metadataOutput.metadataObjectTypes = [.ean13] 25 self.session.startRunning() 26 } 27 } 28 }catch{ 29 print("エラーが起きました") 30 } 31 } 32 33 } 34 35 36 func metadataOutput(_ output:AVCaptureMetadataOutput, didOutput metadataObjects:[AVMetadataObject],from connection: AVCaptureConnection){ 37 for metadata in metadataObjects as! [AVMetadataMachineReadableCodeObject]{ 38 if metadata.stringValue == nil{ 39 continue 40 } 41 print(metadata.type) 42 print(metadata.stringValue!) 43 44 dismiss(animated: true, completion: nil) 45 } 46 47 } 48 49 50 51 52 53 54 55

補足

開発環境はSwift4
iOS12が対象
Xcode10.2.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

他の方法というのであれば

  1. Delegate方式

これは実装に手間がかかります。Delegateの理解がなければ使えません。
2. AppDelegateに最後に読み取った時のデータを保持させる
これが一番簡単でしょう。 ただし、いろいろな問題をはらんでいます。

お説教

使い方を理解するのが難しいです。

なぜ質問でそれらの理解を得ようとしませんでしたか?

僕ならこれはクロージャが適切と考えます。

投稿2019/06/04 02:05

MasakiHori

総合スコア3384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Haruto513

2019/06/11 23:56

回答から随分とお返事が遅くなってしまい申し訳ございません。 回答を見て、いろいろ調べたところどうやらクロージャが最適解かと思われたので、それで解決策を模索してみました。 教えてくださり、ありがとうございました。
guest

0

ReaderVC(共通のバーコード読み取りViewController)で読み込んだ文字列を「各ViewControllerのテキストフィールド」へ、受け渡したいってことですよね。

汎用的に作るのであれば、すでに出ていますがクロージャか、もしくはデリゲートパターンのようなものを使えば良いです。

あとは、少し汎用性は落ちますが、ReaderVCにUITextFieldのインスタンスを渡せるようにしておいて、
バーコード読み取り完了時に、そのテキストフィールドのtextに文字列を流し込むように作っておくのも手です。
(なお、汎用性が落ちると書いたのは、テキストフィールド以外に使えないからです)

投稿2019/06/04 01:58

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Haruto513

2019/06/11 23:56

回答から随分とお返事が遅くなってしまい申し訳ございません。 回答を見て、いろいろ調べたところどうやらクロージャが最適解かと思われたので、それで解決策を模索してみました。 教えてくださり、ありがとうございました。
guest

0

自己解決

コメントの内容などを参考にさせていただいたところ、やはりクロージャが最適解かと思わましたので、いろいろと調べた結果以下のような方法で解決することができました。

swift

1//VC1 2 3@IBOutlet weak var Textbox1: UITextField! 4 5@IBAction func ReadBtn1(_ sender: Any) { 6 let Reader = ReaderVC() 7 Reader.Closure1 = { (text: String) -> Void in self.Textbox1.text = text } 8 present(Reader, animated: true, completion: nil) 9}

swift

1//VC2 2 3@IBOutlet weak var Textbox2: UITextField! 4@IBOutlet weak var Textbox3: UITextField! 5 6 7@IBAction func ReadBtn2(_ sender: Any) { 8 let Reader = ReaderVC() 9 Reader.Closure2 = { (text: String) -> Void in self.Textbox2.text = text } 10 present(Reader, animated: true, completion: nil) 11} 12@IBAction func ReadBtn3(_ sender: Any) { 13 let Reader = ReaderVC() 14 Reader.Closure3 = { (text: String) -> Void in self.Textbox3.text = text } 15 present(Reader, animated: true, completion: nil) 16}

swift

1class ReaderVC: UIViewController, AVCaptureMetadataOutputObjectDelegate { 2 3private let session = AVCaptureSession() 4 5var Closure1: ((String) -> Void)? 6var Closure2: ((String) -> Void)? 7var Closure3: ((String) -> Void)? 8 9. 10. 11. 12 13func metadataOutput(_ output:AVCaptureMetadataOutput, didOutput metadataObjects:[AVMetadataObject],from connection: AVCaptureConnection){ 14 for metadata in metadataObjects as! [AVMetadataMachineReadableCodeObject]{ 15 if metadata.stringValue == nil{ 16 continue 17 } 18 print(metadata.type) 19 print(metadata.stringValue!) 20 21 let CodeString = metadata.stringValue! 22 Closure1?(CodeString) 23 Closure2?(CodeString) 24 Closure3?(CodeString) 25 26 dismiss(animated: true, completion: nil) 27 } 28 29 } 30 31

これで目的の動作は達成しました。ありがとうございました。

投稿2019/06/12 00:23

Haruto513

総合スコア52

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問