LettersBa
LettersBa

Reputation: 767

Play sound when press back button (No Animation)

I have a code that play sounds when the user tap the back bar button in navigation bar, here is the code:

@property(strong,nonatomic) SoundPlayer *soundPlayer;

- (IBAction)voltar:(id)sender{
    [self.soundPlayer PlaySound:@"back" extension:@"mp3" loops:0];
    [self.navigationController popViewControllerAnimated:YES];
}

My code works very well, but I have a problem! I want to make a different type of animation when my view disappear, and for this I need to set the popViewControllerAnimated to NO.

When I do this kind of thing my player don't play sound! But why? I think because with NO animations the view will dealloc and the sound not will play, when animation is YES the sound play very well, because there must be a short delay until the view out of the scene.

My last try is with ViewWillDisappear

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.soundPlayer PlaySound:@"back" extension:@"mp3" loops:0];
}

Here is the animation that I use to dismiss my view:

-(void)setAnimation{
    CATransition* transition = [CATransition animation];
    transition.duration = 0.3;
    transition.type = kCATransitionFade;
    transition.subtype = kCATransitionFromTop;
    [self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
}

How I can solve this problem?

Solution

I can solve this problem creating a code that will sleep my code before view goes out:

[NSThread sleepForTimeInterval:0.1f];

I believe it is not the most professional way to solve this kind of thing, but ...

Solution 2

Hey we can use a callback when the transition finish :D

-(void)setAnimation{
    CATransition* transition = [CATransition animation];
    transition.duration = 0.3;
    transition.type = kCATransitionFade;
    transition.subtype = kCATransitionFromTop;
    transition.delegate = self;
    [self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
}

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
    [self.soundPlayer PlaySound:@"back" extension:@"mp3" loops:0];
}

Well I think thats the best way and professional way to solve this problem (Better than Sleep that jerry-rig)

Correction

Well I realized some test on this code and see that the animationDidStop don't play a sound, the code that play sound is viewDidDisappear, but why?

Lets think... When I give delegate to self in my animation, my code owes the execution of a code when the animation stop, even when everything is taken from the scene (I think).

But in this time the viewDidDisappear is called... and execute the song. So... All I needed to do is giving the delegate to my animation and put the sound inside viewDidDisappear and delete the method animationDidStop (Like a bug, strange...)

Upvotes: 0

Views: 196

Answers (1)

mmacdougall
mmacdougall

Reputation: 11

Your current view controller is likely going out of memory and losing reference to soundPlayer.

While you could totally use a singleton to manager sound playback you might be better off using a delegation/block pattern here:

In your current view controllers header you could:

@protocol ViewControllerBLifeCycleDelegate : NSObject
- (void)vcWillDisappear:(UIViewController *)vc;
@end

@interface ViewControllerB : UIViewController
@property (nonatomic, weak) id<ViewControllerBLifeCycleDelegate> delegate;
@end

In the implementation of the current vc:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.delegate vcWillDisappear:self];
}

And finally you can make the presenting view controller the delegate of this view controller and fire your sound in that controller

@interface ViewControllerA () <ViewControllerBLifeCycleDelegate>
@property (nonatomic, strong) SoundPlayer *soundPlayer;
@end
@implementation ViewControllerA
- (void)presentNextViewController {
    ViewControllerB *vc = [[ViewControllerB alloc] init];
    vc.delegate = self;
    [self.navigationController pushViewController:vc animated:YES];
}

- (void)vcWillDisappear:(UIViewController *)vc {
    [self.soundPlayer PlaySound:@"back" extension:@"mp3" loops:0];
}
@end

Upvotes: 1

Related Questions