Reputation: 767
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
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