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

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

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

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

Swift

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

Q&A

1回答

532閲覧

[ARKit]カメラロールの写真のUIImageを持つSCNNodeを使ってgestureしたい

fokurofechi719

総合スコア10

Xcode

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

Swift

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

0グッド

0クリップ

投稿2019/01/08 15:41

編集2019/01/11 11:20

swiftでARKitを使って、カメラロールで取得した写真を拡大縮小できるような機能を実装しています。

発生している問題・エラーメッセージ

UIPinchGestureRecognizerのターゲットを変更し、コード上のエラーは出ず、実装できたのですが、写真を空間上に映し出せても、ピンチするとエラーが発生し、アプリがクラッシュします。

該当のソースコード import UIKit import SceneKit import ARKit class GestureViewController: UIViewController { @IBOutlet var sceneView: ARSCNView! let defaultConfigulation: ARWorldTrackingConfiguration = { let configuration = ARWorldTrackingConfiguration() configuration.planeDetection = .horizontal configuration.environmentTexturing = .automatic return configuration }() private var lastGestureScale: Float = 1 override func viewDidLoad() { super.viewDidLoad() sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints] sceneView.autoenablesDefaultLighting = true //let configuration = ARWorldTrackingConfiguration() //sceneView.session.run(configuration) } //override func didReceiveMemoryWarning() { //super.didReceiveMemoryWarning() override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) sceneView.session.run(defaultConfigulation) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) sceneView.session.pause() } //ボタンをタップしたら→showUIImagePicker @IBAction func photoButtonTapped(_ sender: Any) { showUIImagePicker() } //カメラロールから画像を取得する private func showUIImagePicker() { if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { let pickerView = UIImagePickerController() pickerView.sourceType = .photoLibrary pickerView.delegate = self pickerView.modalPresentationStyle = .overFullScreen self.present(pickerView, animated: true, completion: nil) } } //UIImageをsceneViewに貼る //createPhotoNodeで作ったSCNNodeをsceneViewに追加 private func setImageToScene(image: UIImage) { if let camera = sceneView.pointOfView { let position = SCNVector3(x: 0, y: 0, z: -0.5) let convertPosition = camera.convertPosition(position, to: nil) let node = createPhotoNode(image, position: convertPosition) self.sceneView.scene.rootNode.addChildNode(node) let pinch = UIPinchGestureRecognizer( target: node, //ここがおかしいと思われます。。。 action: #selector(type(of: self).scenePinchGesture(_:)) ) pinch.delegate = self sceneView.addGestureRecognizer(pinch) } } //SCNNodeを作る private func createPhotoNode(_ image: UIImage, position: SCNVector3) -> SCNNode { let node = SCNNode() let scale: CGFloat = 0.3 let geometry = SCNBox(width: image.size.width * scale / image.size.height, height: scale, length: 0.00000001, chamferRadius: 0.0) geometry.firstMaterial?.diffuse.contents = image node.geometry = geometry node.position = position return node } //ジェスチャーで呼ばれるメソッドを定義 @objc func scenePinchGesture(_ recognizer: UIPinchGestureRecognizer) { if recognizer.state == .began { lastGestureScale = 1 } let newGestureScale: Float = Float(recognizer.scale) let diff = newGestureScale - lastGestureScale let createPhotoNode = SCNNode() let currentScale = createPhotoNode.scale createPhotoNode.scale = SCNVector3Make( currentScale.x * (1 + diff), currentScale.y * (1 + diff), currentScale.z * (1 + diff) ) lastGestureScale = newGestureScale } } extension GestureViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIGestureRecognizerDelegate{ //setImageToSeneにshowUIImagePickerで取得したカメラロールのUIimageを入れる func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info :[UIImagePickerController.InfoKey : Any]) { if let image = info[.originalImage] as? UIImage { setImageToScene(image: image) } picker.dismiss(animated: true, completion: nil) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true, completion: nil) } private func gestureRecognizer(_: UIPinchGestureRecognizer, shouldRecognizeSimultaneouslyWith shouldRecogunizeSimultaneouslyWithGestureRecognizer: UIGestureRecognizer) -> Bool{ return true } }

試したこと

setImageToSceneのインスタンスをUIPinchGestureRecognizerのターゲットに指定しようとしましたができませんでした。

補足情報(FW/ツールのバージョンなど)

GestureViewControllerはCocoapodsを使っています。

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

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

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

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

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

guest

回答1

0

createPhotoNodeは関数であってSCNNode型ではないです。
関数として呼び出してください。

投稿2019/01/09 04:18

takabosoft

総合スコア8356

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

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

fokurofechi719

2019/01/11 11:24

ありがとうございます。初歩的なミスでした。コードを修正し、実装できたのですが、ピンチジェスチャーをしてみるとエラーが発生してしまいます。UIPinchGestureRecognizerのターゲットの箇所が正しく動作しないのですが、ご確認頂けますでしょうが。よろしくお願い致します。
takabosoft

2019/01/15 02:30

targetは、誰に対して「scenePinchGesture」をコールするか?という指定なので、nodeではなくselfでいいはずです。 あとたぶんですが、 private func gestureRecognizer... shouldRecognizeSimultaneouslyWith関数がprivateになっていますが、これはうごきません。 privateを外し、 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool としてください。 正しい関数名はUIGestureRecognizerDelegateの定義を見に行けばわかります。 関数名(型名)が少しでも違うと呼ばれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問