SpriteKit Game slows down - ios

I am writing an iOS app. It has a tab bar controller and one of the tab displays a view which has a collection view - it lists different mini games.
When I tap on the particular item, I show a view which consists of a both UIView and SKView. SKView presents the SKScene where most of the game play happens. There is a close button which closes this view and user is back to collection view.
Now everything works fine for first few iterations - Tap on a item in collection view, it shows a game and can play without hassle and close it. Animations are smooth. But if I just keep opening and closing this view, soon it becomes sluggish and animations are slower and slower. It also makes other parts of my app sluggish. I am clearing SKScene, deleting its children, also removing their actions. Instruments don't show any retail or memory leaks. Not sure whats going wrong. Please help!

Okay, answering my own question. NEVER EVER use NSTimer in SpriteKit. That was the problem in my case. Replacing it with update method fixed things for me.

Related

iMessage Extension - I can not interact with UICollectionView until I try to swipe to another app and then come back

The view is loaded, cells are shown, everything looks fine, but when i click on a cell, or try to scroll down, nothing happens. When I swipe to the left or right and try to switch to another app, the view becomes responsive and reacts to touches and scroll. I don't have to switch to another app completely, just swipe (drag) my app view a little to the left or right, and the collection view becomes responsive. Any ideas? :)
Thanks
I see this when debugging, but not standalone. The simulator is the worst offender, but it happens on-device as well.
If debugging, I've noticed the extension becomes usable when the memory resource gauge in Xcode is populated. Until then everything seems frozen.

iOS Now Playing View Similar To Music/Spotify App

I am trying to figure out how to create a "Now Playing" view similar to the one in the Music app and the Spotify app.
Here are a few images of what I'm trying to re-create:
Creating the view is not the problem. The part I'm having trouble with is how to keep the view on the screen at the bottom with the now playing information on it, but then when clicked, flicked, or swiped up, make it show like a modal.
Is this something that can be set up in Storyboard, or is it completely custom? How would you set this up?
Thank you in advanced for the help.
My guess is for Spotify it's custom as their implementation predates storyboards being... I'll use the term "friendly" to 3rd party developers.
However if you're building with the latest Xcode and iOS SDK this should be fairly easy to accomplish by building a container view controller wherein the child view would be everything in the upper quadrant, and you would effectively make that parent viewcontroller (with the now playing view area on the bottom) the root view controller.
As for the flicking / tapping, that's probably just a typical gesture recognizer that loads a modal. I can't recall if Apple's implementation is panning, but Spotify's is. My guess with them is as you as you tap down they load a new VC that's mostly obscured off screen and that's what actually gets panned in.

How do I keep a UILongPressGestureRecognizer active while switching from a UIViewController to another

At some point in my app, a user can move a UIView after a long press on that view. This works fine.
When the view passes over a specific region, the app has to switch to another UIViewController. The moving view is attached to this new controller. So far so good.
The problem is that now the moving view is not moving anymore (i.e. it doesn't follow the finger of the user) :-(
Seems this issue is related to the UILongPressGestureRecognizer that was fired in a ViewController that is not active anymore.
Any idea how I could handle that ?
ofcourse there might be a requirment to use a UIPanGesturerechognizer,
why dont you enable or add it to the parent view on long press?
You should implement touchesBegan, touchesEnded etc to handle moving of your view. This way, when you're switching the controller, you can still move that view.
Anyway, this idea seems to be weird at least and I'd reconsider app architecture on your place.

Unwind segue to view controller containing SpriteKit's SKView is extremely slow

I've just started playing around with SpriteKit, and this issue pretty much immediately cropped up. If I have a view controller whose view is an SKView, pushing another view controller on top of it (say, a pause menu or an end game menu) and then unwinding back to the view controller with the SKView takes a noticeable amount of time, in my experience on a 4S and a 5, about a second and a half.
You can test this using the default Hello World template. I set it as the root controller of a navigation view and stuck a button in the navigation bar to trigger a push segue to a new view controller. The second view controller contains a button which triggers an unwind segue. When the button gets pressed, it stays highlighted for about a second and a half, and then finally the segue happens, which is incredibly jarring to the user.
I've glanced through the SpriteKit documentation and didn't notice anything written about the proper use of segues, is this just a bug or is it considered bad practice to push new views on top of an SKView? Instead, should I be using SKNodes/SKScenes to present my pause and end game menus, thereby always keeping the SKView on screen?
I had a similar issue and found this helpful. I was planning on using multiple UIViewControllers to navigate to different sections of my game like a menu screen, game over screen etc. but it was painfully slow. After refactoring my app to use a single UIViewController whose view is of type SKView, and creating a new scene for each screen I wanted, it started to work properly. At first I thought that this would be a pain because the controller would end up getting unmanageable, but found that most of logic was incapsulated in each SKScene and the controller was used to present new scenes only.
Also, you should note that adding UIKit controls to the SKView from an SKScene is acceptable. This is what I am doing to avoid having to reinvent the wheel every time I need a UIScrollView, UIButton or any other UIKit control. Of course you will have to remove the UIKit stuff you don't want to share between scenes when you transition.
Could it be possible that the SKView (or the scene) deallocates while the menu storyboard is presented? That would explain the delay when returning to the scene. Set a breakpoint in the corresponding dealloc messages of custom view/scene subclasses or use Instruments to check for the view and scene being among the live objects while the menu is presented.
Another possibility could be textures being removed from memory and then having to be reloaded. There could be an automatism in Sprite Kit, hard to say.
Try changing the way your storyboards are connected, for example have a "main menu" storyboard before the sprite kit view. It would be interesting to see if you get the same effect entering the view (repeatedly) as you do going back to it.
FWIW I only did a few tests with SK and storyboards but haven't noticed such a delay.

Load all view controllers at the launch

I have created an iPad app that has 10 view controllers that swipe left and right to and from each other, and each have 2-10 pages for a vertical UIScrollView. The problem is only the first controller loads at the launch, so each swipe initially takes 10 seconds to load. After the initial swipe I can swipe back and forth with ease, but I would rather have all the load time at the beginning so the user isn't left wondering what's happening.
Is there a way to load everything at once?
Should I even be using UIViewController subclass for this?
Thanks!
You can allocate and initialize them all in the application delegate (I think these go in the applicationDidFinishLaunching method, but I'm not at my computer to verify that is the best place). You may want to set their isHidden property to YES (except for the one you want to show first).
Once they are loaded this way, the applications view controller can be used to change the hidden property when you want a view to show or be hidden.
If each view really takes 10 seconds to load, you will have an initial load time when the application starts that is 10 seconds times the number of views you are loading. But once they are loaded, you shouldn't have that delay anymore.
Update:
If you want to animate the transitions from one view to another, you will have to use more than the isHidden property (that can't be animated). But you can deal with that later, and still start off by allocating and initializing like I described above.

Resources