Fidget Spinner Animation Swift? - iphone

I've got a request to make a fidget spinner animation inside one shopping app, its meant to give the user a 'feel' before clicking buy so its a UIImageView that needs to be animated. I've added a custom single touch gesture recognizer that allows the user to spin/rotate the view, however the image now only rotates and stops as soon as the user lets go, what would be the best way to keep the 'velocity' going? Think of how something would be done with SpriteKit?

I left a comment regarding angular velocity and momentum but wanted to answer this question so the next person who needs help knows a way to do this.
Angular velocity is the speed of the spinning. What you want to do is apply an angular impulse which will start the spinning. The mass and angular momentum will slow it down as time passes, just like the actual physics behind the fidget spinners.
Add this to the touchesBegan method in the fidgetSpinner class
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
fidgetSpinner.physicsBody?.applyAngularImpulse(1)
}
Or add it to the scene but check that the touch was inside and on fidgetSpinner.
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first?.location(in: self)
if fidgetSpinner?.contains(touch) {
fidgetSpinner.physicsBody?.applyAngularImpulse(5)
}
}

Related

How to suspend touchesBegan and only use touchesMoved vice versa?

At the moment I am programming a game in swift, Xcode and I would like the user to be able to choose what controls they want (either slide or tap). As of now I have been able to make my SKNode slide in the main game scene, as well as respond to tapping. However I have found that the SKNode shakes constantly when you slide (as the touchesBegan function thinks I'm tapping on the screen).
If anyone knows the best way to suspend one of the functions while the other stays active please let me know :)
For example:
The user chooses to play the game by sliding, I would like to suspend the touchesBegan function but keep the touchesMoved active.
There is a delegate method to check if one gesture fails, if is true the other gesture is recognized. For example, in my project I have two gestures, tap once and tap twice and I used:
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if otherGestureRecognizer.numberOfTouches == 2 {
return true
}
return false
}
For more information check Apple's reference:
https://developer.apple.com/documentation/uikit/uigesturerecognizer/1620006-shouldrequirefailure

How to record how long a user has been on an SKScene?

I would like to figure out how to record the amount of time a player has spent on a particular SKScene? I want to record this information and then grab the amount of time, add it to UserDefaults() and then eventually add it to an SKLabelNode.
Should I use NSTimer? A point in the right direction would be great!
Thanks :D
You can implement these two methods of SKScene:
Called immediately after the scene has been initialized or decoded.
func scene​Did​Load()
Called immediately after a scene is removed from a view.
func did​Move(to:​ SKView)
In each method you can get the current time and then perform the difference.

How to catching doubleClick events from NSOutlineView in ViewController?

I am trying to catch doubleClick events from my NSOutlineView to be passed to my ViewController. My idea is to catch doubleClick events and to get the selected row from my OutlineView
What I did so far was subclassing the NSOutlineView in order to overwrite mouseDown
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
if event.clickCount >= 2 {
...
}
}
That works well however I don't know how to pass this event to my ViewController. The ViewController is already implementing the NSOutlineViewDelegate protocol.
I guess that the solution is not far away but somehow I am stuck.
UPDATED
Although you can set up NSGestureRecognizer for single click and NSClickGestureRecognizer for double clicks in OSX, You should probably be using the doubleAction property of the NSOutlineView directly.
Here's an example of how to set it up
This comes from a another of the Wenderlich tutorials, and there is a good discussion on SO already

tvOS - strange touchesCancelled received

I am having a user input issue in my tvOS SpriteKit project - if I try to move the finger quickly after touching the touchpad on the tv remote I do have touchesCancelled called while if I wait a little while (1s) after first touch (wihout releasing my finger) all works like charm and I can use this tiny interface for steering in my game.
Unfortunately there is no specific code I can paste.
this guy:
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) { ... }
is being called by the system in case a quick finger move but not called if I wait for 1-2 seconds before I start moving my finger.
Any idea what I could have done wrong?
ah .... UISwipeGestureRecognizer from previous Scene was hanging around :(
func removeAllGestureRecognizers(){
for recognizer in self.view!.gestureRecognizers!{
self.view!.removeGestureRecognizer(recognizer);
}
}
fixed my issue ...

Swift: how to disable user interaction while touch action is being carried out?

I'm working with sprite kit and if the user touches the screen, the actions within
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
}
}
are carried out. While they're being carried out, however, the user can still tap the screen and the app tries to run the actions again.
How do I disable touch interaction/the actions within the touch func while the actions are running?
To disable user interaction app-wide, use:
UIApplication.shared.beginIgnoringInteractionEvents()
UIApplication.shared.endIgnoringInteractionEvents()
(as of Swift 5 this is deprecated)
Try to get the view from the touch object and then dissable the user interaction on it.
touch.view.isUserInteractionEnabled = false
In Swift 3.0 is:
self.view.isUserInteractionEnabled = false
You can use boolean class variable to stop interaction while method is performing, and after that you can just change value of boolean, at the end of the method.
Use UIApplication.shared.beginIgnoringInteractionEvents() at the end of the first method, then change value of boolean and then use another method with start line UIApplication.shared.endIgnoringInteractionEvents().
- SwiftUI
SomeView()
.allowsHitTesting(false)
For SwiftUI, expanding on #mojtaba-hosseini answer.
You wanna make sure you fill your view with some color, except Clear color (you can always change opacity). I've also added blur to hide elements. Here's what worked for me:
SwiftUI:
ZStack{
SomeView().blur(radius: 12)
Rectangle()
.fill(Color.white.opacity(0))
.allowsHitTesting(false)
}
Another way to disable user interactions like scroll or button taps, but attach an action to user taps (for example a message to users that this feature is coming or behind a paywall):
SwiftUI:
VStack{
SomeView().blur(radius: 12)
}
.contentShape(Rectangle())
.onTapGesture {
print("No access!")
}
just go to storyboard and uncheck this option in any object which u want to disable the interaction of the user
If you want to disable a Buttons user's interaction, just do this when the screen loads.
self.btnname.isUserInteractionEnabled = false
If you want to disable the user interaction as a view, it will be same just remove the button name and add the view's name.
If for some reasons, you want to enable interaction, just change "false" to "true".