Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

exiting a void method based on another variable

melinoemelinoe Posts: 17New Users
One of the views in the application simultaneously records video and plays a bunch of core animations. The animations are triggered when the video recording is started. The animations begin in one method and more are triggered with the "- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag" method, using key-value encoding to decide which set of animations should be triggered. Normally the video recording ends at a set point that lines up with the animations ending; however, I need to implement a way to stop the video recording prematurely and also stop the animations as soon as the video recording is stopped. Stopping the video recording is tied to a button; however, I can't find a way to make the animations stop as soon as the button is pressed. I know that [return]; is used to exit void methods prematurely, but short of putting a check to see if the video has stopped and if so to exit the function after every single animation, I can't think of a way to do it, and while that may work it seems like a pretty inelegant solution that puts in a lot of extra code. Is there some way that I'm overlooking? I tried using an NSTimer that ran checks every few seconds but as far as I'm aware NSTimers can only be used to trigger other methods, which won't trigger a [return]; in the main methods that I'm trying to stop.

Replies

  • Duncan CDuncan C Posts: 9,116Tutorial Authors, Registered Users @ @ @ @ @ @ @
    Add a stillRunning BOOL instance variable to your view controller. When the user clicks the stop button, set the bool to false.

    In your animationDidStop method, check that flag, and only start the next animation if the flag is true.

    Deleting "in-flight" animations that are already running is a little more complex. If you're creating CAAnimation objects and submitting them to your view's layer, no problem. Just send a removeAllAnimations message to the layer that's animating. If you're using UIView animations, you need to send a removeAllAnimations message to the layer of each view who's properties you have animated. When you remove in-flight animations, the layer will jump to it's "end state" (The setting of the underlying property that was last set without animation.)
    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • melinoemelinoe Posts: 17New Users
    That was more or less what I thought - so I should just add checks before every animation that will quit the method if the recording has stopped? Like I said in my original post that does seem like a lot of extra code but I'll do it if there isn't another way.
  • Duncan CDuncan C Posts: 9,116Tutorial Authors, Registered Users @ @ @ @ @ @ @
    melinoe said:

    That was more or less what I thought - so I should just add checks before every animation that will quit the method if the recording has stopped? Like I said in my original post that does seem like a lot of extra code but I'll do it if there isn't another way.

    A lot of extra code? It should be just one if statement.

    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • melinoemelinoe Posts: 17New Users
    I tried that but everything ran in order so it would only check it at the one point that I put it at and that was all.
  • Duncan CDuncan C Posts: 9,116Tutorial Authors, Registered Users @ @ @ @ @ @ @
    melinoe said:

    I tried that but everything ran in order so it would only check it at the one point that I put it at and that was all.

    Huh? I can't parse that sentence.
    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • melinoemelinoe Posts: 17New Users
    Sorry. I tried putting an if statement at the beginning of the method that would check the status of an isRecording BOOL, and if it returned no, then to [return]; in the method. But it would only check at the beginning (or wherever I placed the if statement); so if I stopped the recording it would continue running until the animationDidStop method began and then it would stop, instead of quitting the method as soon as I stopped the recording.
  • RickSDKRickSDK Posts: 1,240Registered Users @ @ @ @
    you need to recheck the global BOOL value before each frame of the annimation. thats pretty simple to do.
  • Duncan CDuncan C Posts: 9,116Tutorial Authors, Registered Users @ @ @ @ @ @ @
    RickSDK said:

    you need to recheck the global BOOL value before each frame of the annimation. thats pretty simple to do.

    It sounds like the OP is doing Core Animation animation, not manual frame-based animation.

    Thus he should set a flag that tells his animation completion method not to start any more animations, and then remove all animations from the layer(s) that is(are) being animated.

    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • melinoemelinoe Posts: 17New Users
    Correct, I am using Core Animations, but they're in chunks. So there's a chunk of animations in the initial method, and when one of those animations ends it triggers another chunk of animations in the animation completion method, and when those are over there's another animation in the initial method that triggers another chunk of animations in the animation completion method, etc etc. Originally everything was in the one method but there were way too many CALayers trying to load at one time and breaking it up so that it loaded in sections (and removed all previous layers/animations) works a lot better. But they're all pretty short animations, so I could put a check of the BOOL before each one.
  • RickSDKRickSDK Posts: 1,240Registered Users @ @ @ @
    i would think you should be able to break them into smaller and smaller chunks until you get the look and feel you need.
  • melinoemelinoe Posts: 17New Users
    So I've tried putting the if statement before one of the animations as a test, but when I press the button to stop the recording it doesn't stop the method. It does the other thing that the if statement says it should do (stop the audio that's playing) but all of the animations continue and the layers persist even though I've created another method that should remove all of the layers and animations that is called when the if statement condition is fulfilled. I'm not really sure why it isn't working; here's the code I'm using.

    if (isRecording == NO) { if (player.playing == YES) { [player stop]; } [self removeAll]; return; }

    This is placed inside of the main void method with animations inside of it. I'm pressing the button that stops the recording and the player is stopping but the function isn't exiting and the layers and animations are sticking around and continuing to go through their motions. Here's a snippit of the removeAll method:

    -(void)removeAll { [layerOne removeFromSuperlayer]; [layerTwo removeFromSuperlayer]; [layerThree removeFromSuperlayer]; // etc etc [self.view.layer removeAllAnimations]; }
  • RickSDKRickSDK Posts: 1,240Registered Users @ @ @ @
    im not familiar with your annimation code but it seems to me you are going to have to break all your annimations down so that no single annimation runs for more than a second. If you want something to run longer than a second you will have to break it into several small annimations and have a check in between each segment that checks if it needs to stop or play the next segment.

    It appears you are hoping that pressing the button will magically interupt your annimation but you need to code it that way instead.
  • melinoemelinoe Posts: 17New Users
    I'm not hoping it'll magically interrupt the animation, I know that it's just gonna have to do it whenever it'll happen. But it's not stopping anything at all, at any point, other than the audio which is the player that's in the if statement. The audio stops as soon as I press the button (which flips the isRecording BOOL from yes to no), which I guess means that [return]; should also be called as soon as I press the button, but the animations just keep going. I've tried setting the sublayers property of the layer that all of the animations are on to nil both in the if statement and also in a different method tied to the button, and nothing happens. At this point I'm at even more of a loss because none of these things that should be working in some way or another seem to be working at all.
  • RickSDKRickSDK Posts: 1,240Registered Users @ @ @ @
    have you tried breaking your annimations into 1 second segments?
  • Duncan CDuncan C Posts: 9,116Tutorial Authors, Registered Users @ @ @ @ @ @ @
    RickSDK said:

    im not familiar with your annimation code but it seems to me you are going to have to break all your annimations down so that no single annimation runs for more than a second. If you want something to run longer than a second you will have to break it into several small annimations and have a check in between each segment that checks if it needs to stop or play the next segment.

    It appears you are hoping that pressing the button will magically interupt your annimation but you need to code it that way instead.

    Or you can set a flag so that no new animations are added, then send a removeAllAnimations message to the layer of every view that has an animation "in-flight." I know that works because I've done it.
    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • melinoemelinoe Posts: 17New Users
    How would I flag it so that no new animations are added? That sounds really useful but I've never seen anything like it before.
  • Duncan CDuncan C Posts: 9,116Tutorial Authors, Registered Users @ @ @ @ @ @ @
    melinoe said:

    How would I flag it so that no new animations are added? That sounds really useful but I've never seen anything like it before.

    If all this is controlled from a single view controller, all your logic can be self-contained in that view controller. If not, you need to add a data container singleton that holds your "don't create new animations" flag.

    Let's say for simplicity that everything is in one VC.

    Add a block_new_animations instance variable to your VC.

    In your code that creates new animations as each animation finishes (animationDidStop:finished) , check the value of block_new_animations first. If it's TRUE, don't start new animations.

    Then, when you want to stop the video and animations, stop the video, set block_new_animations to TRUE and, if you want animations to stop instantly, send a removeAllAnimations message to the layers of all views that have in-flight animations.


    Regards,
    Duncan C
    WareTo

    widehead.gif
    Animated GIF created with Face Dancer, available for free in the app store.

    I'm available for one-on-one help at CodeMentor
  • melinoemelinoe Posts: 17New Users
    Seems to have finally done it; I put a check before every block inside of the animationDidStop method that checked if the video was still recording, and if not to remove all sublayers of the animation layer, remove all animations from those layers, and to break out of the method. Thanks so much for all of your help!!
Sign In or Register to comment.