Swift SpriteKit 3D Touch and touches moved
After trying various other things that didnt work, including UISwipeGestureRecognizer subclasses, I finally figured it out.
The answer was actually staring me right in the face in that same stackOverflow post I linked in my question
iOS 9 Spritekit Double Tap Not Working on iPhone 6S
The solution is to create a property
var startingTouchLocation: CGPoint?
than in touches Began you set that property
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
/// Set starting touch. this is for 3d touch enabled devices, see touchesMoved method below
startingTouchLocation = location
....
}
}
and than add a check in touchesMoved to return from the method until the touch has actually moved.
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
/// WAY 1 - Check if touch moved because on 3d touch devices this method gets called on a force touch.
guard location != startingTouchLocation else { return }
// Your code
...
/// WAY 2 - Add a min distance for the finger to travel in any direction before calling touches moved code
let minValue: CGFloat = 30
guard let startingLocation = startingLocation else { return }
guard currentLocation.y < startingLocation.y - minValue ||
currentLocation.y > startingLocation.y + minValue ||
currentLocation.x < startingLocation.x - minValue ||
currentLocation.x > startingLocation.x + minValue else { return false }
// Your code
....
}
}
Distinguish Swipe from Touch in Spritekit - Swift 3
You can use a gestures state to fine tune user interaction. Gestures are coordinated, so shouldn't interfere with each other.
func handlePanFrom(recognizer: UIPanGestureRecognizer) {
if recognizer.state != .changed {
return
}
// Handle pan here
}
func handleTapFrom(recognizer: UITapGestureRecognizer) {
if recognizer.state != .ended {
return
}
// Handle tap here
}
3D Touch force gesture activates cell tap on touch end
You could create a boolean named isForceTouch which is set to false in touchesBegan, and then once force touch is detected, set it to true. Then in didSelectRowAtIndexPath just return false if isForceTouch is true. It may need tweaking but that should work.
3D Touch and SpriteKit
Yes, you can integrate 3D Touch and SpriteKit.
Using the default SpriteKit game project template (Swift), set your GameScene
to be a UIViewControllerPreviewingDelegate
and implement the protocol's methods, like this:
public class GameScene: SKScene, UIViewControllerPreviewingDelegate {
public func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
return UIViewController()
}
//Pop
public func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
return
}
}
In GameViewController.swift's viewDidLoad
, add the following:
if let scene = GameScene(fileNamed:"GameScene") {
if self.traitCollection.forceTouchCapability == .Available {
registerForPreviewingWithDelegate(scene, sourceView: scene.view!)
}
}
In the delegate method, I am returning an empty view controller. You can create a class-level variable and instantiate this VC with appropriate peek
-type views. Again, a very simple example. If you want to add 3D Touch from an AppIcon interaction, you will need to modify Info.plist and add capabilities from the AppDelegate. There is a good video on this topic. Good luck!
Related Topics
Swift: How to Get Information for an Application Which Is Not Running
Cannot Stop Background Music from Within Game Scenes, Swift 3/Spritekit
Could Not Cast Value of Type Uiview to [Customview] Using Xib
Elegant 'Bounded' Methodology in Swift
Presenting a Uiviewcontroller from Skscene Shows Black Screen
Swift Uikit Dynamics Add Collision Boundary. After Rotation Does Not Work Correctly
How to Use Dispatchgroup/Gcd to Execute Functions Sequentially in Swift
Error "{ Expected After If Statement"
What Does Cloning a Github Repository Mean
Update Firebase Multi-Location with Error: Path Is an Ancestor of Path. Swift
What Does This Mean? Variable Declared Followed by a Block Without Assignment
Change Mkmarkerannotationview Size
How to Make a Function with a Loop Asynchronous in Swift
Nsmanagedobject Subclasses Duplicate Declaration
How to Store the Progress of Progressview into Arraylist as One Element
Why Aren't My Custom Classes Appearing in the Dropdown in Interface Builder