I am using XCode 6 beta 5 with Swift / Scenekit. I have a SCNNode (a 3D SCNText object) that I want to use as a button. How do I connect this to a segue? With storyboard or programmatically? I thought of connecting the code for the SCNNode to a hidden button on the story board which connects to the segue but that seemed kinda hackish.
2 Answers
As far as using the text as a button, load up a new project with the rotating cube. Inside of the handleTouches is exactly what you are looking for.

- 1,124
- 10
- 9
-
I got that far, I want the code to open a new viewcontroller (connect to a segue) – quemeful Aug 13 '14 at 21:07
This is the same case as performing a segue from a map annotation, dynamically choosing between multiple segues from the same table cell, performing a segue in response to SpriteKit event handling, or any other case where you need to perform a segue in response to something that happens in your code instead of in response to the user tapping a control you set up in IB. You need a "manual" segue.
- In the storyboard, create a segue by dragging from the (source) view controller itself to the destination view controller (instead of by dragging from a button or other control). Define an identifier for the segue using the inspector pane.
- When something happens in your code that should trigger the segue, call
performSegueWithIdentifier:
with the identifier you defined. (If this code is inside of the view controller class, you can call it onself
. Otherwise you'll need a reference to the view controller to segue from.)
As @FlippinFun points out, you can find code for touch handling in the SceneKit Game Xcode template. (For those following along at home, the gist of it is to use the view's hitTest
method to find the scene element at the touch/click location.) In there is where you'd call performSegueWithIdentifier
.
But there's a problem -- that template puts its touch handling code inside a view class instead of in the view controller, so the touch handling code doesn't know about the current view controller. Some possible solutions, ranked from "Best MVC architecture" to "Most quick-and-dirty":
Instead of subclassing
SCNView
to implement touch handling code, use aUITapGestureRecognizer
instance instead -- it can call an action method on your view controller, and then you can use the recognizer'slocationInView
method to get a point you canhitTest
with. Since you're still in view controller code there, you can callself.performSegueWithIdentifier
once you get a hit-test result you like.In the
SCNView
subclass, keep a (weak!) reference to the view controller that owns it. Then the view's touch handling code can callperformSegueWithIdentifier
on that view controller. (If you want to keep things abstract so the view doesn't have to know the view controller class, define a protocol.)In the
SCNView
subclass' touch handling code, useself.window.rootViewController
to find the view controller, and cast the result to your view controller class.