I'm trying to figure out how to catch the event that controls the switch tabs on the
UITabBarController. How could I accomplish this?
Implement UITabBarControllerDelegate e.g. in your app delegate's applicationDidFinishLaunching
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
tabBarController.delegate = self;
[window addSubview:tabBarController.view];
}
Then implement either:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController;
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
The first method is called before the view switch and gives you a chance to 'veto' the view switch by returning NO
The second method is called after the view switch has taken place
If you are using storyboard, do this
in didFinishLaunchingWithOptions
UITabBarController *tabBar = (UITabBarController *)self.window.rootViewController;
[tabBar setDelegate:self];
Also in AppDelegate, keep <UITabBarControllerDelegate>
And then
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
//Write your code here
}
Have a look at the following method in UITabBarControllerDelegate:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
Tells the delegate that the user
selected an item in the tab bar.
Better late than never. In case of swift 4 you can do it in the following way.
tabBarViewController.delegate = self
And implement UITabBarDelegate in your class.
You will get the callback in
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
//Stuff to do
}
Is UITabBarControllerDelegate what you're looking for, particularly -tabBarController:didSelectViewController:?
Related
I have created two instances of a MasterViewController derived from UIViewController class
_masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController_iPhone" bundle:nil];
// second instance with same class and duplicate nib view
_favItemMasterVC = [[MasterViewController alloc] initWithNibName:#"favMasterViewController_iPhone" bundle:nil];
Both the MasterViewController_iPhone & favMasterViewController_iPhone view are same.
Now I want to check which of the UIViewController is currently selected(eg:on tabbar).
How can i find the difference between both objects?
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[_favItemListMasterVC class]]
{ // it is always called in both cases}
isMemberOfClass: // is also not working
How to check the difference?
Not sure I have understand what are you doing, but if _favItemListMasterVC and _masterViewController are pointing to the same VCs added to the UITabBar, you can check it simply comparing pointers
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (viewController == _favItemListMasterVC)
{
//the visible view controller is _favItemListMasterVC
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (viewController == _masterViewController)
{
}
else if (viewController == _favItemMasterVC)
{
}
}
I think you can use tag to check which is which. Tag is property of a UIView Set the tag value in the two xib files. And check the tag using code.
To compare objects you can also use:
if([viewController isEqual:_favItemMasterVC])
Currently, Tapping on the same Tab (in which user is working), The App moves to the very first page of that Tab.
I want to disable the tap event on the Tab in which user is working currently.
Any Hint?
You tried tabBarController:shouldSelectViewController: delegate method? I hope that should help you.
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
id currentViewController = tabBarController.selectedViewController;
return (viewController != currentViewController);
}
If all the view controllers of the tab bar controller are UINavigationControllers, you should do it like this.
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
id nextVC = [(UINavigationController *)viewController topViewController];
id currentVC = [(UINavigationController *)tabBarController.selectedViewController topViewController];
return (nextVC != currentVC);
}
For Swift 4 the delegate method looks like this:
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
return viewController != tabBarController.selectedViewController
}
use like below it will work
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if(self.tabBarController.selectedIndex==[[self.tabBarController viewControllers] indexOfObject:viewController])
return NO;
else
return YES;
}
I would like to invoke a certain method whenever the user selects a different tab of a UITabBarController. The following works for actual tabs on the tab bar but not for the 'tabs' on the More controller:
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
[self doSomethingWhenAnotherVCIsSelected]
}
This method seems only to be called when a 'tab' is selected, including the 'more' tab. Whenever another VC on the 'more' tab is pushed, this is not called.
Is there any standard notification mechanism that can be used to detect if a VC was selected on the 'more' tab?
Call the method in the -viewWillAppear of the viewController.
Found the following workaround:
// subclass of UITabBarController
- (void)viewDidLoad
{
moreDelegate=self.moreNavigationController.delegate;
self.moreNavigationController.delegate=self;
...
}
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[moreDelegate navigationController:navigationController willShowViewController:viewController animated:animated];
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[moreDelegate navigationController:navigationController didShowViewController:viewController animated:animated];
[self tabBarController:self didSelectViewController:viewController];
}
I have read the Apple docs - http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/TabBarControllers/TabBarControllers.html#//apple_ref/doc/uid/TP40007457-CH102-SW1 about creating TabBar programmatically. I want to detect the TabBar selection so I have used following delegate methods. I am not sure why but these methods don't get fired when I change the Tabs on my iPhone. Could anyone please provide some thought on what's going wrong here. It would be really helpful. Thanks.
- (BOOL)tabBarController:(UITabBarController *)tbController shouldSelectViewController:(UIViewController *)viewController
{
if (viewController == [tbController.viewControllers objectAtIndex:3] )
{
// Enable all but the last tab.
return NO;
}
return YES;
}
- (void)tabBarController:(UITabBarController *)tbController didSelectViewController:(UIViewController *)viewController {
if (viewController == [tbController.viewControllers objectAtIndex:self.appTabs.count] )
{
//do some action
}
}
Did you forget to set the delegate when you created the UITabBarController?
someTabBarController.delegate = self;
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];
}
}