iOS Spritekit Scrolling Menu - ios

I am implementing a horizontal scrolling menu for a SpriteKit game and have become stuck as to how to go about this. My strategy was originally to add all of my menu items to the scene and just pan the camera horizontally according to swipes.
The problem with this is that the menu is revolving/circular (last item links to the first, etc) so even if I repeated the menu items infinitely, after swiping constantly one direction, I imagine a coordinate limit would be reached and the app would crash.
My next solution is to add one menu item in my camera view, one to the left, and one to the right. Then upon swiping the correct item would move into my camera view via SKAction and the original item would move away. I would then removechild the farthest node from the camera, and add the next item to the scene in the direction toward which I swiped. This way my x range (in points) would only be -displayWidth to displayWidth. The problem with this is that I would need to animate all of the menu items at the same time, and as they are separate nodes I have not seen a way to synchronize their animation.
Also I need to check the position of elements on the menu items and change their shaders when they reach the border of the screen. SKActions seem to block the SKScene update method so I am ideally trying to avoid SKActions.
Is there any viable strategy that I am missing here?

Since this is only a menu, it is ok to be a little inefficient.
What you do is have your menu cloned 2 times (so you have a total of 3). You place one of the clones to the left, and one to the right.
You then add all 3 of these into a parent SKNode. You should now have one SKNode with the 3 menu items in a long string. Make sure your anchor point is (0.5,0.5)
You then run the animation to pan left or right on the parent SKNode, with the condition that whenever you pass the edge of your original main menu, you jump in the opposite direction the width of the menu.
So let's say our menu is 400 (-199,200) points wide, and our screen is 300 points wide (-149,150). Once the parent point -200 (menu point 200 or right side of menu) aligns with screen point -150, you move the parent point to 200 (so menu point is -200 or left side of menu).
Since you are moving the parent node, all the clones will follow suit, and you only need to run 1 action.

I recommend using UIKit to create such a menu instead of SpriteKit. UICollectionView should be good for such a task.

Related

Swift: How to drag image view to "snap" up against edge of the next image view

Using Swift 4 in XCode, I have several image views on the screen. I have added a gesture recognizer to one, and am able to move that image around the screen with a pan action.
What I'd like is that when I move that image NEXT to another image view on the screen, it "snaps" into place right next to it. (imagine magnetic lego blocks - and when one gets close to the next one, it snaps and attaches) -- as opposed to, say, being able to drag the movable image on TOP of the static image.
Can anyone guide me toward an answer, as I don't know what this concept is called.
(I'm not really trying to use animation, as it should only move based on a user's swipe.) Any tutorial links would be appreciated! Thanks!

changes to allowsCameraControl (swift 4)?

I have a simple SCNScene with an object placed in the center (for example, a cube). BEFORE the latest update to Swift 4, I enabled allowsCameraControl and the user could then rotate and manipulate (zoom in/out) the cube. Now, (Swift 4, iOS 11) with the exact same code, when the user manipulates the cube, SOMETIMES the direction you swipe your finger matches the direction the cube moves, while other times, the direction you move your finger causes the cube to move the opposite direction! It is NOT something that is always backwards or always correct, it can change as quickly as swiping one direction (correct cube movement), raising your finger, going back and trying to continue the same motion, but now the second swipe makes it rotate back the wrong way!
It almost seems like it's trying to use some specific point in the scene as a 'reference' of some kind. Like if that point is on the front of the object, a swipe left makes it move left. But if that point gets moved to the 'back' of the object, the next swipe left still moves the POINT left, but because it's in the 'back', moving left translates into the front of the object moving right. (with the same thing for up and down!)

How to tie together gestures and animation

I'm as beginner as you can get when it comes to iOS animation.
I know you can do fixed (non-gesture-controlled) animations, where you animate a property of a view over a fixed period of time. This however is entirely different than using a gesture to control the animation.
You know how you fold a sheet of 8x11 paper to put it in an envelope and mail it... you fold it in thirds. Well basically, my boss wants an interface such that 2/3rds of it is shown on the screen at a time, and the other third is slid on/off screen with a gesture. So basically, the screen would show either thirds 1 and 2, or thirds 2 and 3 depending on whether you swipe left or right.
Now this also means doing things like snapping/rubberbanding, bouncing, acceleration/deceleration, sticky. I have no clue where to even start to do something like this. I'm assuming those types of motions are not already built into any of the iOS framework and if you want snapping/rubberbanding, bouncing, acceleration/deceleration, you'd have to program that entirely from scratch.
Like how would a view know my artificial snap/bounce points are, and sticky behavior, such that you remove your finger from the screen before an arbitrary position is reached, and the view bounces back to it's previous position.
Where would you suggest I start on researching how to drive animations with gestures?
I suggest you take a look at Core Animation. You can do some really complex animations including accelerations, deceleration, bounce and others.
You could easily create a UIPanGestureRecognizer to track when someone has dragged their finger across the screen. Attach an action wasDragged to your gestureRecognizer
From the documentation:
A panning gesture is continuous. It begins (UIGestureRecognizerStateBegan) when the minimum number of fingers allowed (minimumNumberOfTouches) has moved enough to be considered a pan. It changes (UIGestureRecognizerStateChanged) when a finger moves while at least the minimum number of fingers are pressed down. It ends (UIGestureRecognizerStateEnded) when all fingers are lifted.
In wasDragged check what state the gestureRecognizer is in. If state is UIGestureRecognizerStateChanged, then you can adjust the size or position of your UIView so that it appears like you are dragging it out. If state is UIGestureRecognizerStateEnded, check whether the point at which the gesture ended is greater than your threshold point (e.g. halfway across the screen). If it isn't, then snap the view back using an animation, if it is then snap the view into where you want it.
Hope this makes sense.

Swift : Create region to UIPanGesture

I have this design here : http://imgur.com/XHMBUdj
I would like to allocate the left half of the screen(splitting vertically) to panning up and down for the blue bars and allocate the right half of the screen(splitting vertically) to panning up and down for the red bars.
I can already use UIPanGestureRecognizer, however, I just need help making the region in which if the user pans on the right side of the screen, "this" happens and if the user pans on the left side, "this" happens.
A friend of mine recommended using UIBezierPath. Could someone help me out? Code will be much appreciated!
I looks like it would be easier to have two UIPanGestureRecognizers.
In your view, you can add a subview that take up the left half on the screen that contains the blue bars and the microphone and add another subview that is on the right half of the screen containing the red bars and the music icon.
Then you can create two separate UIPanGestureRecognizers and add one to each of the views. Then each side will have its one recognizer that will take care of the side detection for you.

How to make jQuery Mobile scrollview scroll infinitely left and right so the elements repeat back on themselves?

Basically the same as this question: How to make an infinitely long scroll view on iPhone? but using jQuery Mobile not objective C.
I'm using this plugin: http://jquerymobile.com/test/experiments/scrollview/scrollview-direction.html in particular the example under "Horizontal Scrollview". I want it to loop back on itself so when the user gets to the far right, it will go back to the start and if they scroll left from the start it will go to the end.
I'm not bothered if the solution uses the scrollview plugin in particular or not just that it can have a similar effect.
UPDATE: I eventually did a different way as moving elements to the end or the start of the list seemed flickery with jQuery Mobile scrollview on an iPhone.
What I did was copy all of the li elements within the ul 3 times, so that it was 4 times longer. Then at the start of the script, position the scroll point at the start of the 3rd copy (so the left most point of the screen was exactly half way along the length of the list).
Then whenever the scroll position went beyond the start of the 4th copy, simply move the scroll position back to the middle (offset by how many pixels over it went). Then the same in reverse, triggering it went it went beyond the start of the 2nd copy. Reason I needed 4 copies was so there was a bit of leeway when you scrolled left fast and it went beyond the start of the 2nd copy.
So essentially you want to do something simular to what I did for: http://bbh.co.uk?
The logic is very simple, let's say you have 7 panels, the first thing I did was work out where the 0 point of the movement, that is where the centre of the 7 panels, in this case it's the 4th as we'd have 3 on the left and 3 on the right.
With this 0 point we can then decide where panels will go onces a scroll has occurred, say the user scrolls 2 from the left to the right, this means our 0 point becomes -2, therefore we move two from the right to the front of the left, i.e. we prepend them to the list.
The easiest way to manage it was with an array, since we can .push(), .pop(), .shift() and .unshift() the panels.
Once we had the logic in order we placed each set the CSS position of each panel as absolute and then calculated its position depending on where it was within the array, for example panel 0 would be at 0px left in the container and panel 7 would be at panel.width * 7 and so on.
You then need to make sure that the container is at the centre, that initial 0 point and boom, you've got some infinite scrolling.

Resources