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を使っています。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/11 11:24
2019/01/15 02:30