tabBarController didSelectViewController in AppDelegate is not called - ios

I have used the Xcode tab bar controller template and am trying to detect when a user selects a tab in my tab bar controller. In AppDelegate.h I have:
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate> {
UITabBarController *tabBarController;
}
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
and in AppDelegate.m I have:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
tabBarController.delegate = self;
return YES;
}
- (void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController
{
NSLog(#"Selected tab bar button!");
}
I have not connected any outlets for the Tab Bar Controller scene listed in Main.storyboard because I couldn't figure out the right connection to make, if one is even necessary. I also haven't made any references to this delegate method in my FirstViewController or anywhere else, because the various ways I tried to do that didn't work. Could someone help me understand how to get this working?

You can add tab bar controller by selecting UIViewController(FirstViewController in your case) and choose Editor >> Embed In >> Tab Bar Controller.

Eliminate the UITabBarController *tabBarController; declaration in AppDelegate.h (line 4) and replace
tabBarController.delegate = self;
with
self.tabBarController.delegate = self;
in AppDelegate.m.

Related

iOS - pushViewController not working after conversion to xCode 9 / iOS 11

I saw my iOS app isn't allowed to be downloaded from the app store with the most recent upgrade to iOS 11, so I'm trying to update it. I have it in Xcode 9, and I've managed to now get the app started on my iPhone 6. However, I can't seem to get it to display after my initial screen display.
For example, the initial display successfully displays and shows a button called "start". That should pop up another display when you press it, but it doesn't (although it is reaching the code which displays it).
Here's the code, in a class named "StartController.m", which should be calling up the display:
NSLog(#"nav controller = %#", self.navigationController);
// push question controller onto the stack
[self.navigationController pushViewController:questionController animated:YES];
// the nav controller owns it now, we can release it
[questionController release];
Debugging shows this code is successfully called when the button is pressed, but after the release of questionController, nothing happens.
Here's the declaration of the questionController in StartController.h:
#interface StartController : UIViewController <ADBannerViewDelegate>{
QuestionController *questionController;
And here's the declaration of the same in StartController.m:
#implementation StartController
#synthesize questionController, settingsController, nextLevelViewController, appState;
The initial view (with the "start" button) is successfully displayed with this code in the "didFinishLaunchingWithOptions" method of the app delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// create the start controller
self.startController = [[StartController alloc] init];
// transfer to it - not animated because it's the first view
[navController pushViewController:startController animated:NO];
// add the current nav controller view to the window view heirarchy
// [window addSubview:navController.view];
[self.window setRootViewController:startController];
// release becasause now the navController has it
[startController release];
// show the start controller
[self.window makeKeyAndVisible];
return YES;
}
For reference, here's the declaration of the navController in the app delegate header:
#interface QuizAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navController;
StartController *startController;
}
#property (readonly) BOOL iPad;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) StartController *startController;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
And here's the declaration in the implementation:
#implementation QuizAppDelegate
#synthesize window;
#synthesize startController;
#synthesize navController;
I tried not to post too much code for fear of obscuring the problem, but I'll add it if requested. Any ideas what the problem might be?

Passing data between view controllers and tab bar controller

i've got this method in my dashBoardViewController.m
- (void)demoSetup
{
self.tabBar.tintColor = [UIColor colorWithRed:(160/255.0) green:(97/255.0) blue:(5/255.0) alpha:1]; // set the tab bar tint color to something cool.
self.delegate = self; // Just to demo that delegate methods are being called.
}
#pragma UITabBarController Delegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
NSLog(#"UITabBarDelegate: shouldSelectViewController...");
return YES;
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSLog(#"UITabBarDelegate: didSelectViewController...");
}
- (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray *)viewControllers
{
NSLog(#"UITabBarDelegate: willBeginCustomizingViewControllers...");
}
- (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
{
NSLog(#"UITabBarDelegate: willEndCustomizingViewControllers...");
}
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
{
NSLog(#"UITabBarDelegate: didEndCustomizingViewControllers...");
}
i've got 4 linked on it, and a view with Facebook login
i need to pass from the view that contains Facebook login 2 datas (FBID, FBUSER) to my dashBoardViewController and from it pass the same data to all of my tabs, is it possible?
this is the dashBoardViewController.h
#import <UIKit/UIKit.h>
#import <FacebookSDK/FacebookSDK.h>
#import "BFPaperTabBarController.h"
#interface dashBoardViewController : BFPaperTabBarController <UITabBarControllerDelegate,FBLoginViewDelegate>
#property (weak, nonatomic) IBOutlet FBLoginView *loginButton;
#property (retain, nonatomic) NSString *id;
#property (retain, nonatomic) NSString *first_name;
#end
Create FBID, FBUSER properties in the required viewcontroller classes.Then write a method to create a shared instance of the view controller in the view controller class
+ (instancetype)sharedInstance {
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
This method will return a shared instance of MyViewController class. This is a static object.
MyViewController *myViewController = [MyViewController sharedInstance];
set your properties as myViewController.fbid = yourvalue or myViewController.first_name = yourvalue
You have to implement this shared instance method in all of your view controllers. So that you can create static objects and set a not static property as static
Here's my understanding of the view controller setup.
----- FaceBook Login VC
|
--> TabBarController --|----- VC1
|
|------VC2
|
------VC3
If the diagram looks right and you are trying to pass data between FaceBookLogin and VC -1, V-2 and VC -3.
You can do this by creating a subclass of TabBar Controller. In your subclass declare two properties for FBID and FBUSER.
If the use successfully logs in using "FaceBook Login" page, then set these properties in the custom tabBar controller.
You can now access these properties from any VC that is part of the tabbar controller.
Let me know if you need to see some code or need more detailed explanation.

How to access tabBarController from AppDelegate.m?

This is my storyboard:
I am trying to access tabBarController from a method inside AppDelegate.m
This is AppDelegate.h:
#import <UIKit/UIKit.h>
#import <FacebookSDK/FacebookSDK.h>
#import "STAlertView.h"
#interface demo_AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, strong) STAlertView *av;
#end
And this is AppDelegate.m:
#import "demo_AppDelegate.h"
#import "demo_Friends_ViewController.h"
#implementation demo_AppDelegate
-(void)showFriendReqAlert:(NSNotification *)pNotification{
NSLog(#"Hello from showFriendReqAlert:");
NSLog(#"Root: %#", [self.window.rootViewController.navigationController.tabBarController viewControllers]);
}
....
....
....
....
#end
My main motive is when this method showFriendReqAlert: is called, a red badge is shown to the third tab bar item which is Friends. But whenever i try to select tabBarItem, it says null in NSLog.
I have also tried the following:
self.window.rootViewController.navigationController.tabBarController
self.window.rootViewController.tabBarController
but nothing works. Any help?
Thanks!
I believe (sorry for believing here ;-) that the TabBarController should be your first controller and your navigationBarController must come afterwards as it does not make much sense for the navigationController (if you change a tab) what to push/pop.
I suggest that you remove your first DemoViewController and following NavigationController and that your first Controller is your TabBarController (simply set "Is Initial View Controller" in IB).
Then you can access your tabBar like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UITabBarController *tbc = (UITabBarController *)self.window.rootViewController;
}
Swift 5:
guard let tabBarController = window?.rootViewController as? UITabBarController else { return }

UITabBarButton without switching to another view

Does anyone know of a way to have a UITabBarButton that, rather than segueing to another view controller, will perform another function, e.g. call a method?
My iPad app utilises a tab bar but the client wants the right-most button to perform a check for updates on a server; however I can't seem to to figure out how to have a button that won't switch views when pressed. I tried deleting the segue but that removes the button as well.
-EDIT-
screenshot and code snippet added for clarity. The tab labelled Sync is the one I want not to open a viewController:
AppDelegate.h:
#interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UIViewController *viewController;
#end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.window makeKeyAndVisible];
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
tabBarController.delegate = (id)self;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil];
return YES;
}
and:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
NSLog(#"vc = %#", viewController);
return YES;
}
Look at the UITabBarControllerDelegate method :
– tabBarController:shouldSelectViewController:
If selectViewController == your last tab bar, return NO and perform others actions
EDIT :
Look at the example I've made :
AppDelegate.h
#interface ISAppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
tabBarController.delegate = (id)self;
return YES;
}
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
// here check if "viewController" is your last tab controller, then return NO and perform some actions you need
if (viewController = self.lastTabController) {
// do some actions
return NO;
}
return YES;
}

Why does my iOS app crash when trying presentModalViewController?

I've been banging my head against this all day, it seems like something simple but I can't figure it out.
I've got an iOS app that I created using the "View-based Application" template in XCode. Here is essentially the code I have:
AppDelegate.h:
#import <UIKit/UIKit.h>
#interface AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MainViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet MainViewController *viewController;
#end
AppDelegate.m:
#import "AppDelegate.h"
#import "MainViewController.h"
#implementation AppDelegate
#synthesize window, viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
MainViewController.h:
#import <UIKit/UIKit.h>
#interface MainViewController : UIViewController {
}
-(IBAction) button:(id)sender;
#end
MainViewController.m:
#import "MainViewController.h"
#import "ModalViewController.h"
#implementation MainViewController
...
-(IBAction) button:(id)sender {
ModalViewController *mvc = [[[ModalViewController alloc] initWithNibName:NSStringFromClass([ModalViewController class]) bundle:nil] autorelease];
[self presentModalViewController:mvc animated:YES];
}
#end
There's nothing of interest in the ModalViewController.
So the modal view should display when the button is pressed. When I press the button, it hangs for a second then crashes back to the home screen with no error message.
I am stumped, please show me what I'm doing wrong!
There's nothing of interest in the ModalViewController.
Although there may not be anything of interest, there could still be something causing the problem.
Does your View Controller override the function loadView?
A problem that has got me a few times is if you don't call [super loadView]; first in your overriden loadView method. Not doing this causes a crash when moving into that View Controller.
Good luck in trying to solve this one!
N

Resources