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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

Q&A

解決済

1回答

1033閲覧

xcodeでQRコードを用いた画面遷移

退会済みユーザー

退会済みユーザー

総合スコア0

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/04/02 07:37

前提・実現したいこと

XcodeでQRコードを用いたゲームを作ろうとしています。
QRコードで読み取った文字が正解であれば、次のページに進むようにしたいのですが、QRコードを読み取った後に、どのようにそのデータを用いて画面遷移させればいいのかわかりません。
また、同じQRコードを二回以上読めないようにしたいのですがそれはどうしたらいいでしょうか。回答よろしくお願いします。

(例えば、QRcodeの値がaだった場合は、次のviewcontrollerへ、値がbだった場合は、読み取り失敗(何も起こらない)というようにしたいです。)

該当のソースコード

お恥ずかしいですが、QRコードを読み取る機能はYouTubeを参考に製作しました。

import UIKit
import AVFoundation

class QRcodeViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

@IBOutlet var videoPreview: UIView! var stringURL = String() enum error: Error { case noCameraAvailable case videoInputInitFail } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. do { try scanQRCode() } catch { print("QRコードの読み取りに失敗しました。") } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects:[Any]!, from connection: AVCaptureConnection!) { if metadataObjects.count > 0 { let machineReadableCode = metadataObjects[0] as! AVMetadataMachineReadableCodeObject if machineReadableCode.type == AVMetadataObject.ObjectType.qr { stringURL = machineReadableCode.stringValue! } } } func scanQRCode() throws { let avCaptureSession = AVCaptureSession() guard let avCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video) else { print("カメラがありません。") throw error.noCameraAvailable } guard let avCaptureInput = try? AVCaptureDeviceInput(device: avCaptureDevice) else { print("カメラの読み込みに失敗しました。") throw error.videoInputInitFail } let avCaptureMetadataOutput = AVCaptureMetadataOutput() avCaptureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) avCaptureSession.addInput(avCaptureInput) avCaptureSession.addOutput(avCaptureMetadataOutput) avCaptureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr] let avCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: avCaptureSession) avCaptureVideoPreviewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill avCaptureVideoPreviewLayer.frame = videoPreview.bounds self.videoPreview.layer.addSublayer(avCaptureVideoPreviewLayer) avCaptureSession.startRunning() }

}

バージョンは、xcode9,swift 4,iOS 11です。

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

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

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

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

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

guest

回答1

0

ベストアンサー

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects:[Any]!, from connection: AVCaptureConnection!)

はSwift4から

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) ``` に変更になっているのでメソッドが呼ばれないのではないでしょうか?(呼ばれていたら私の勘違いです。申し訳ございません。) 画面遷移はUINavigationControllerを使用している前提で記載します。 下記のようなだといかがでしょうか? 「同じQRコードを二回以上読めないようにしたい」がどこまでの範囲かわからな買ったので、QR読取画面表示中という範囲で考えました。 もしさらに長期的に読み取れなくしたい場合はDatabaseやUserDefaultの使用などもあります。 ``` // クラス変数としてSetを宣言する var urlSet: Set<String>! override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 画面表示時にSetをクリアする urlSet = [] } ``` ``` func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { if metadataObjects.count > 0 { let machineReadableCode = metadataObjects[0] as! AVMetadataMachineReadableCodeObject if machineReadableCode.type == AVMetadataObject.ObjectType.qr { stringURL = machineReadableCode.stringValue! // 一度でも読み込んだことがあるQRコードは処理を終了 guard !urlSet.contains(stringURL) else { print("読み込み済みのQRコードです。") return } if stringURL == "a" { // "a"だった場合はSecondViewControllerに遷移する let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) // Main.storyboard上にSecondViewControllerというViewControllerがあるとする let vc = storyboard.instantiateViewController(withIdentifier: "SecondViewController") self.navigationController?.pushViewController(vc, animated: true) } else if stringURL == "b" { print("QRコードの読み取りに失敗しました。") } else { // aでもbでもない場合は何かする? }        // 読み込んだQRコードをSetに保持しておく urlSet.insert(stringURL) } } } ``` 参考記事: [https://qiita.com/Simmon/items/6c3d6bcd6bfffbfd970d](https://qiita.com/Simmon/items/6c3d6bcd6bfffbfd970d) [https://shinjism.com/blog/2017/10/qrcode.html](https://shinjism.com/blog/2017/10/qrcode.html) [https://qiita.com/Saayaman/items/4f3f63048d1d5924a829](https://qiita.com/Saayaman/items/4f3f63048d1d5924a829)

投稿2018/04/02 22:13

newmt

総合スコア1277

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

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

退会済みユーザー

退会済みユーザー

2018/04/03 14:27

丁寧な説明本当にありがとうございます。できれば、半永久的に同じQRコードを読み込めないようにしたいのですが、その場合はどのようにすれば良いのでしょうか。 教えていただけると本当に助かります。
newmt

2018/04/03 21:42

例えばDBやUserDefaultsに読み込んだQRコードのデータ(文字列を保存しておき)、QRコードを読み込んだ際にすでにデータが存在する場合は2回目以降読み込まれていると判断できます。 UserDefaultsはアプリの設定など小さいデータの保存などに使いますので、今回の場合はDBの方が良いのかと個人的には思っています。 参考記事: DBだとRealmというライブラリがよく使われます。 http://grandbig.github.io/blog/2017/05/06/swift3-realm/(ちょっとswiftのバージョンが古いのでそこは変更が必要ですが、基本的な操作方法は同じです) UserDefaultsについて https://i-app-tec.com/ios/nsuserdefaults.html
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問