I have an instance of AVAudioPlayer running inside one of my tabs. It is activated through an IBAction.
I would like the music to stop when a user clicks on another tab.
How would I go about doing this?
I've tried theAudio.stop; in viewDidLoad, but that didn't work.
In your UITabBarControllerDelegate implement the following method;
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
This is called whenever the user selects a new view in the controller.
I think you could also override the following method in the UIViewController that's playing the audio
-(void) viewDidDisappear:(BOOL)animated
Wire up a UITabBarControllerDelegate to your main view, then listen for (void)tabBarController:(UITabBarController *)tabBarController didSelectItem:(UITabBarItem *)item
When you get that event, find the player in your object model and stop it.
I happened upon this post while trying to answer the same exact question. Just in case anyone else is still looking, I finally figured out how to do it with an NSNotificationCenter. Basically, an NSNotificationCenter sends "broadcasts" a message to the entire application. If an "observer" happens to be listening, as you can see below, a given method is called. The code looks like this:
In your App Delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
// Make sure you add this so that your tab bar calls its delegate methods
tabBarController.delegate = self;
}
// Optional UITabBarControllerDelegate method (this will be commented out by default - uncomment it)
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
// Create the NSNotificationCenter
[[NSNotificationCenter defaultCenter] postNotificationName:#"tabChanged" object:nil];
}
In your view controller:
- (void)viewDidLoad {
[super viewDidLoad];
// Register an observer to stop audio recording/playing on tab change
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(tabChanged)
name:#"tabChanged"
object:nil];
}
- (void)tabChanged {
#"Received Notification!";
if([player isPlaying]) {
[player stop];
}
}
Related
How to dismiss popover when application enters in background?
You can do this using the delegate method in appdelegate.m file
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//put your dissmiss popover code here
}
it is better to register your controller for UIApplicationDidEnterBackgroundNotification or UIApplicationWillResignActiveNotification and dismiss it whenever your app goes to background, this will make your life quite easier i feel.
registering for notification in your viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMethod)
name:UIApplicationDidEnterBackgroundNotification object:nil];
implement the method and
-(void)myMethod{
// dismiss popview here
}
finally un-register from the notification in your view controller
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Send an NSNotification in your app delegate's willResignActive method, and listen for it in your view controller that contains the popup, and have it dismiss said popover when the notification is received.
try this
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//[popover dissmissPopoverAnimated:YES];
}
I need to handle home button pressing in my app.
When user presses home button in my DetailedViewController I need to trigger method that will [self.navigationController popViewControllerAnimated:YES].
Help me please.
How could it be done?
Check out - (void)applicationWillResignActive:(UIApplication *)application method in you app delegate. It will catch the event. And then your can handle it as you need. For example, post notification using default notification center and get it in class where you need to do something.
What you want exactly? you want to get back to Home(root) or just want to get back to the previous page?
just try out with this code in which you get back to your starting or home controller
[self.navigationControler popToRootViewControllerAnimated:YES];
As Павел Оганесян has described :
// post notification
- (void)applicationWillResignActive:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"TestNotification" object:self];
}
Now in DetailedViewController .m file
// add observer
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveTestNotification:) name:#"TestNotification"
object:nil];
}
- (void) receiveTestNotification:(NSNotification *) notification
{
// do the needful
}
Hope it helps you...
I have a uiwebview that plays a youtube video. How can I handle the done button action?
Right now, when I tap the done button it changes back to my app main menu (not the menu that was supposed to dismiss to) and it just freezes. Can anyone help me please?
Ps: the menu where the uiwebview is located, was previously presented modally.
The YouTube plug-in player is itself a modal view controller. It is returning to its presentingViewController when the done button is pressed. Its presentingViewController is not your modal view controller but is instead the viewController that called [presentModalViewController:animated:] to present your modal view controller. Since the original modal view controller is still active, the app behaves badly.
To fix the problem,
1) Track whether the modal view controller has been presented but not dismissed.
2) In the viewDidAppear method of the presenting view controller, if the modal view controller was presented and not dismissed, dismiss and present it again.
For example, in controller that is presenting the modal web view controller:
- (void) presentModalWebViewController:(BOOL) animated {
// Create webViewController here.
[self presentModalViewController:webViewController animated:animated];
self.modalWebViewPresented = YES;
}
- (void) dismissModalWebViewController:(BOOL) animated {
self.modalWebViewPresented = NO;
[self dismissModalViewControllerAnimated:animated];
}
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.modalWebViewPresented) {
// Note: iOS thinks the previous modal view controller is displayed.
// It must be dismissed first before a new one can be displayed.
// No animation is needed as the YouTube plugin already provides some.
[self dismissModalWebViewController:NO];
[self presentModalWebViewController:NO];
}
}
This thread is very useful and help me to find the problem!
The answer of lambmj works fine, but I found a better way.
In presenting view controller:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.presentedViewController) {
UIViewController *vc = self.presentedViewController;
[vc dismissModalViewControllerAnimated:NO];
[self presentModalViewController:vc
animated:NO];
}
}
Hope this helps!
#Gdx Wu
#lambmj
Thanks for your methods, they work fine. But there is some small problem that after clicking the done button & jumping directly to the presenting view controller, we need to dismiss the presented modal view controller and present it again, which would bring some dither(like flash) between these view controller switches.
Based on this, I highly recommend #IsaacCisneros 's method which would switch seamlessly.
Simply remove UIWebView when it enters full screen; add back UIWebView when it exit full screen. Sample code below assuming a UIViewController with subview of UIWebView, and your UIWebView should have youtube iframe.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Add observer for "Done" button click
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerWillExitFullscreen:)
name:#"UIMoviePlayerControllerWillExitFullscreenNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerDidEnterFullscreen:)
name:#"UIMoviePlayerControllerDidEnterFullscreenNotification"
object:nil];
}
- (void)viewDidDisappear:(BOOL)animated {
// Remove observers for "Done" button click
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
}
- (void)playerWillExitFullscreen:(NSNotification *)notification {
// Before exit full screen, add back UIWebView that have been removed earlier
[self.view addSubview:self.webView];
}
- (void)playerDidEnterFullscreen:(NSNotification *)notification {
if (self.presentingViewController) { // UIWebView is presenting the build-in movie player controller
[self.webView removeFromSuperview]; // Built-in movie player controller is already entering full screen mode
}
}
When I'm doing a half-page curl modal transition:
How can I tell when the page has been restored back to it's current state? I want to call something when the "settings" view has been closed.
I tried to use viewWillAppear:(BOOL)animated but it doesn't seem to get called when closing the view. Any ideas?
You can register an NSNotificationCenter observer on your master view and post the notification on your background view. And instead of viewWillAppear you can use viewDidLoad.
// EDIT: sample code to get a touch gesture in a given rect
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if ([[event allTouches]count] == 1) {
UITouch *t = [[touches allObjects]lastObject];
CGPoint p = [t locationInView:self.view];
if (p.y < 200) NSLog(#"above 200");
}
}
In your viewDidLoad, register a Notification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updateView:)
name:#"updateRootView"
object:nil];
Now this is the notification that we call
- (void) updateView:(NSNotification *) notification
{
/* notification received after the page is uncurled */
}
The calling method:
- (void) unCurlPage
{
// All instances of TestClass will be notified
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateRootView" object:self];
}
And don't forget to dealloc the notification
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
ViewWilAppear is a UIViewController message/method. If you are only changing views, it won't get called. What does the code you are using to close the settings view look like?
Edit
It sounds like you need to refactor a bit. Assuming all this is handled by the parent UIViewController for this settings view, you could implement something like:
- (void)settingsPanelOpen {
// present the modal
// hook to inform of opening (if necessary)
}
- (void)settingsPanelClose {
// dismiss modal
// hook to inform of closing
}
Then settingsPanelClose could have a hook into it if you need to know when the settings closes.
The other thing you could do is subclass UIViewController as SettingsViewController and override the viewDidDisappear: method to kick off a SettingsDidSave notification or otherwise inform your app that it has closed.
I would like my UITableView to reloadData once my app is active again, after a user exits the application. I know I need to implement (in my app delegate):
- (void)applicationDidBecomeActive:(UIApplication *)application
but im not sure how to reference the current UITableView?
UPDATE:
My UITableView is a separate controller. It is actually presented as follows
AppDelegate > Root View Controller > Pushes UITabBarController modally which has a UITableViewController
following up on Ole's answer above
add this when initializing the viewcontroller
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(becomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
add the actual method in the controller
- (void)becomeActive:(NSNotification *)notification {
NSLog(#"becoming active");
}
be sure to clean up the notification
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
If you can't access your view controller from the app delegate, you could also have your controller listen to the UIApplicationDidBecomeActiveNotification notification.
you can create your class called TableViewManager. in there register list of UITableView so that you can refresh any table you want.
it's like this, in yourTableViewManager class, you have a method called
- (void)RefreshTableView:(UITableView *)tableView {
if(tableView != nil)
[tableView reloadData]; }