Can I combine an SKAction runBlock with the SKNode - runAction:completion:? function? - ios

when I call the runAction:completion:? function of a SKSpriteNode, and pass in a SKAction runBlock action the call back routine never gets called.

Well, this is possibly because SpriteKit has no way of knowing when your block actually stopped affecting the node in question. If the API was better designed maybe it'd give you a way of calling the completion from your block, but it doesn't. However, you can call whatever you'd call in the completion block yourself within your block.
Edit: Yes, the called (in this case SpriteKit) does know when your block ends executing, but your block may perform deferred calls that will further affect the node in question, so it can't be certain the action really ended. For example, think of a block that triggers a timer that varies a certain property over time.

Related

UIViewPropertyAnimator - simply stop all animations, rather than a specific one?

In UIViewPropertyAnimator, is there a way to just stop all UIViewPropertyAnimator animations?
Or perhaps simply get all current animations - then of course you could stop them all.
Can this be done?
Or do you really have to
(a) do only one per UIViewPropertyAnimator,
and,
(b) keep a reference to each of those?
Every animation has to have atleast one UIViewPropertyAnimator instance. In order to stop the animation, we have to explicitly call stopAnimation(_:) on the animator instance.
A way would be to make a factory class to fetch UIViewPropertyAnimator instance and keep track of it in a set or array. And then use this factory class to stop or start all the animations at once. Or use one UIViewPropertyAnimator to perform all your animations and stop it.

In SpriteKit does touchesBegan run in the same thread as the SKScene update method?

In the Apple documentation here Advanced Scene Processing it describes the update method and how a scene is rendered, but it does not mention when input is processed. It is not clear if this is in in the same thread as the rendering loop, or whether it is concurrent with it.
If I have an object that I update from both the SKScene update method and the touchesBegan method (in this case of a SKSpriteNode) do I have to worry about synchronising the two accesses to my object?
So after a few days with no answer I set up some experiments. By the way, these tests are run on the simulator and not on an actual device, but I think it would be the same.
First test, I set a breakpoint in the debugger on touchesBegan and looked at the stack trace. It appears that touchesBegan is called from the first thread and from the main loop - the same place as the rest of the logic, so this looks good for a singe-threaded approach.
Second test, I overrode the various methods in the scene mentioned in the Advanced Scene Processing link above and added print statements to show th name of each function called. Then I added a print statement to the touchesBegan method.
On running the app, the output was:
update
didEvaluateActions
didSimulatePhysics
didApplyConstraints
didFinishUpdate
touchesBegan in scene
update
didEvaluateActions
didSimulatePhysics
didApplyConstraints
didFinishUpdate
update
and this pattern was repeated whenever I clicked.
No amount of clicking gave me anything else than touchesBegan being called between the didFinishUpdate (that is, the end of one cycle) and the update (the beginning of the next).
Conclusion: touches processing happens in the main loop before the update method is called. It is therefore not necessary to synchronise resources between the two methods.

Thread syncing animations in iOS across functions

I'm writing an iOS app in Objective C. In one my classes (a View Controller), I have 2 different functions. Each of these functions, within it, has a call to an animation (UIView animateWithDuration). Let's call these functions Function A and Function B, and the animations they call within themselves Animation A and Animation B respectively. Animation A is sort of long and delayed, while B is pretty quick.
I absolutely need the animation in Function B to only start running once the animation in Function A completes. i.e. Animation B has to run after Animation A completes.
I CANNOT call Animation B from Animation A's completion block, because Animation B needs parameters available only to Function B in order to run:
FunctionA()
{
AnimationA()
}
Function B(x, y, z)
{
AnimationB(x, y, z)
}
How on earth do I solve this problem? I've tried creating a new separate queue and then stacking the Animation A and B calls on that, but it still doesn't work. What inevitably seems to happen is that, I'm guessing the actual UIView animateWithDuration call will invariably spawn its own thread, and so the block of code that runs it that I place on the queue will return as completed even while it's still going on, because it's the completion handler that is anyways going to run when it's done (which I can't use for the reason mentioned previously).
Any suggestions?
Thanks

how to pause DynamicAnimator

i keep seeing these methods,
– dynamicAnimatorDidPause: required method
– dynamicAnimatorWillResume: required method
But i've not found a way to call them. Ive set up an animator and called <UIDynamicAnimatorDelegate> in the .h, but I cannot seem to call pause on the self.animator for some reason.
Anyone have any tips for me?
Thanks!
Those are delegate methods, which means that you don't call them, they get called for you. You implement a delegate to get informed about certain events
The dynamic animator pauses by itself when all movement stops. Try adding a gravity effect with no collision boundaries. The animator should pause when all dynamic items fall offscreen.

Is -scrollViewDidScroll: called on a background thread?

I'm experiencing something odd with -scrollViewDidScroll:
In every call I obtain the last object from an NSMutableArray, and add another object to that NSMutableArray.
But it seems the NSMutableArray does not store the object in time before the next call and when I try to get the last inserted object, it is not the last one I inserted. There is something async happening.
Is this a known issue? How can I see if it is called in the Main Thread?
It's called on the main thread. You can check by adding a breakpoint in Xcode in -scrollViewDidScroll:, and looking at the call stack.
Alternatively NSThread has some pretty useful methods here, such as +isMainThread, or +callStackSymbols.
NSThread Docs

Resources