Pushing View Controller with Two Nav Controllers - ios

I've got an app where I am pushing a modal view controller. It is working fine, but I am concerned I haven't coded it in the most correct fashion. I have instanstiated two navigation controllers, which seems a bit dodgy to me.
Basically I've created a tab bar controller with 3 tabs, then made one of those tabs / view controllers the root. Later I am (using some home-grown markup on core text) popping a view controller when the user touches a particular word in a paragraph. The pushed view controller has a back button which works fine and the app seems to be OK.
Like I said it all works, but it seems I am coding in circles here. Is this correct?
AppDelegate.h
#import <Foundation/Foundation.h>
#interface AppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate>
{
UIWindow *window;
UITabBarController *tabBarController;
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UITabBarController *tabBarController;
#end
From AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ViewController *viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
ViewController2 *viewController2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
ViewController3 *viewController3 = [[ViewController3 alloc] initWithNibName:#"ViewController3" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:viewController];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:nav, viewController2, viewController3, nil];
self.tabBarController.delegate = self;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
ViewController3.h
#import <UIKit/UIKit.h>
#import "JSCoreTextView.h"
#import "PopupViewController.h"
#class JSTwitterCoreTextView;
#interface ReadingViewController : UIViewController <JSCoreTextViewDelegate>
{
JSTwitterCoreTextView *_textView;
UIScrollView *_scrollView;
}
#end
From ViewController3.m
Here I am instantiating another navigation controller. Is this a good idea?
- (void)textView:(JSCoreTextView *)textView linkTapped:(AHMarkedHyperlink *)link
{
PopupViewController *popupVC = [[PopupViewController alloc] initWithNibName:#"PopupViewController" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:popupVC];
[nav setModalPresentationStyle:UIModalPresentationFullScreen];
[nav setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentModalViewController:nav animated:YES];
}
From PopupViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(done:)]];
}
- (void)done:(id)sender
{
[self.parentViewController dismissModalViewControllerAnimated:YES];
}

It appears the answer is "yes". I was under the impression there is a single Navigation Controller for the app, but it's more like one per tab, depending on if there are going to be further pushes from that tab.

Related

NavigatorController is nil

AppDelegate.m
_viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:_viewController];
nav.navigationBar.barStyle = UIBarStyleBlackOpaque;
[_window addSubview:nav.view];
ViewContoller.m
UINavigationController *nav = self.navController;
[nav pushViewController:controller animated:YES];
I don't know why the UINavigationController always nil.
Please help!!
Instead of adding navigationController's view as window's subview try adding navigationController as window's rootViewController
window.rootViewController = nav;
[_window makeKeyAndVisible];
homeViewController = (mainStoryboard.instantiateViewControllerWithIdentifier("register") as? RegisterViewController)!
let navigationController :UINavigationController = UINavigationController()
navigationController.pushViewController(homeViewController, animated: true)
navigationController.navigationBarHidden = false
window?.rootViewController = nil
window?.rootViewController = navigationController
window?.makeKeyWindow()
#interface AppDelegate ()
#property (strong, nonatomic) UINavigationController *navigationController;
#end
//In Your Appdelegate didfinishlaunching method:
self.window = [[UIWindow alloc] init];
[self.window makeKeyAndVisible];
self.navigationController = [[UINavigationController alloc] initWithRootViewController: YourViewController];
self.window.rootViewController = self.navigationController;
//In Your View controller:
[self.navigationController pushViewController:controller animated:YES];
NEW SOLUTION
try this
in AppDelegate.m
#implementation AppDelegate
{}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *_navController = [[UINavigationController alloc] init];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = _navController;
ViewController* _viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[_navController pushViewController:_viewController animated:YES];
return YES;
}
in ViewContoller.m now this will work:
UINavigationController *nav = self.navigationController;
[nav pushViewController:controller animated:YES];
OLD SOLUTION
try this code
in AppDelegate.h be sure to have this at least
#interface AppDelegate : NSObject <UIApplicationDelegate>
{}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#end
in AppDelegate.m at least this
#implementation AppDelegate
{}
#synthesize window=_window;
#synthesize navController=_navController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *_navController = self.window.rootViewController;
UIViewController* _viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[_navController pushViewController:_viewController animated:YES];
return YES;
}
#end
in storyboard be sure to have created a NavigationController binded to a ViewController, defined as initial view controller and binded as root view controller for the binded view controller
in the app general settings tab be sure to have set the storyboard in the deployment info section (also in this section you could set status bar style)
in ViewContoller.m now this will work:
UINavigationController *nav = self.navigationController;
[nav pushViewController:controller animated:YES];
to edit the navigationBar style you can do it this way
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
}

Passing data between tabbarcontroller which have content view and view controllers

I am using xib instead of storyboard.
AppDelegate.m
ViewController1 *ViewController1 = [[ViewController1 alloc] init];
ViewController1.title = NSLocalizedString(#"1", #"1");
ViewController2 *ViewController2 = [[ViewController2 alloc] init];
ViewController2.title = NSLocalizedString(#"2", #"2");
BannerViewController *_bannerViewController1;
_bannerViewController1 = [[BannerViewController alloc] initWithContentViewController:ViewController1];
BannerViewController *_bannerViewController2;
_bannerViewController2 = [[BannerViewController alloc] initWithContentViewController:ViewController2];
_tabBarController = [[UITabBarController alloc] init];
_tabBarController.viewControllers = #[_bannerViewController1,_bannerViewController2];
self.window.rootViewController = _tabBarController;
[self.window makeKeyAndVisible];
ViewController1.m
#import "ViewController1.h"
#import "ViewController2.h"
ViewController2 *cvc = [[ViewController2 alloc] initWithNibName:nil bundle:nil];
cvc.strReceiveValue= "Testing";
ViewController2.h
#property (strong, retain) NSString *strReceiveValue;
ViewController2.m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"strMortgageAmount: %#", strMortgageAmount);
Any idea why I failed to get the value? I was thinking this could be related to initWithContentViewController.
**
See update below
**
If I understand the question correctly, you are creating a tab bar controller (in AppDelegate?) and wish to pass information to the view controllers associated with the tab bar controller?
If so, take a look at this:
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
[tabBarController setDelegate:self];
UINavigationController *dashTVCnav = [[tabBarController viewControllers] objectAtIndex:0];
Then:
DashTVC *dashTVC = [[dashTVCnav viewControllers] objectAtIndex:0];
dashTVC.managedObjectContext = self.managedObjectContext;
dashTVC.uuid=uuid;
Then in DashTVC.h:
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (strong, nonatomic) NSString *uuid;
With this, you pass the managedObjectContect and the uuid to the dashTVC controller.
I hope I understood what you are asking...
+++++++++++++++ UPDATE +++++++++++++++++++++
The original poster was kind enough to give me his sample code. I will post parts of it here with my fix for those who find this through searches in the future
There were several problems, but in short, nothing was being passed to vc2:
1st, nothing was being passed from the appDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CGRect bounds = [[UIScreen mainScreen] bounds];
self.window = [[UIWindow alloc] initWithFrame:bounds];
self.window.backgroundColor = [UIColor whiteColor];
ViewController1 *vc1 = [[ViewController1 alloc] init];
vc1.title = NSLocalizedString(#"VC1", #"VC1");
ViewController2 *vc2 = [[ViewController2 alloc] init];
vc2.title = NSLocalizedString(#"VC2", #"VC2");
//--- I added this as a test
vc2.strReceiveValue=#"foo";
// and now foo shows up in the debug console when vc2 is fixed
_tabBarController = [[UITabBarController alloc] init];
_tabBarController.viewControllers = #[
[[BannerViewController alloc] initWithContentViewController:vc1],
[[BannerViewController alloc] initWithContentViewController:vc2],
];
self.window.rootViewController = _tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Next, it was necessary to modify viewWillAppear in viewController2.m
- (void)viewWillAppear:(BOOL)animated {
// line below missing
[super viewWillAppear:animated];
NSLog(#"output: %#", strReceiveValue);
}
Hope this helps, and enjoy developing for IOS!

AppDelegate and .xib are not implementing properly, but build is successful?

I really don't know how to explain this without pasting all my code, but ill give it a shot. "Assuming" my .hs and .ms are accurate, i have a feeling my .xib is not set correctly, but i cant really paste the code from that. Instead i've zipped the files and uploaded the source code. (if you are brave enough, it's here: http://bit.ly/ZtDkGi ) Im getting a successful build, but my emulator's screen is just black after the app launches.
Essentially, i had to manually add an appDelegate object. i set the class to the appropriate class - but its still not pulling. If someone would be kind enough to help, that would be great.
here's my Test_TableViewAppDelegate.h
#import <UIKit/UIKit.h>
#interface Test_TableViewAppDelegate : NSObject <UIApplicationDelegate>
{
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
#end
here's my new Test_TableViewAppDelegate.m
#import "Test_TableViewAppDelegate.h"
#implementation Test_TableViewAppDelegate
#synthesize window=_window;
#synthesize navController=_navController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//self.window.backgroundColor = [UIColor whiteColor];
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.backgroundColor = [UIColor greenColor];
self.window = window;
UIViewController *fvc = [[UIViewController alloc] init];
UIViewController *rootController = [[UIViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:rootController];
//UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:fvc];
self.navController = nc;
//[self.window addSubview: nc.view];
//[self.window makeKeyAndVisible];
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
return YES;
}
RootViewController.h
#import <UIKit/UIKit.h>
#interface RootViewController : UITableViewController {
NSMutableArray *petsArray;
}
#end
RootViewController.m
#import "RootViewController.h"
#interface RootViewController ()
#end
#implementation RootViewController
and last but not least, main.m ( i think this might be an issue too)
#import "Test_TableViewAppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([Test_TableViewAppDelegate class]));
}
}
thanks in advance. i'd appreciate it :D
in your delegate Test_TableViewAppDelegate
why you adding views two times to the window?
// you could remove these two lines
[self.window addSubview: nc.view];
[self.window makeKeyAndVisible];
//keep these two lines
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
And this view you are adding to the navigationController it is not initalized with any nib name
UIViewController *fvc = [[UIViewController alloc] init];
initialization should be like this instead in your delegate
RootViewController *rootController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:rootController];
I believe the reason that you're getting a black screen is that you are not properly allocating and initializing your navigation controller!
Instead, you should try this code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// create the base window
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.backgroundColor = [UIColor greenColor];
self.window = window;
[window release];
// this is the home page from the user's perspective
FirstViewController *fvc = [[FirstViewController alloc] init];
UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:fvc];
self.navigationController = nc;
[fvc release];
[nc release];
// show them
[self.window addSubview: nc.view];
[self.window makeKeyAndVisible];
return YES;
}
Hope this works!

Combining Navigation Controller with Tab Bar Controller

As I mentioned in the title, I want to add Navigation Controller to my application which already has a Tab Controller. So trying to do the staff something like on this page. Anyway, something is wrong. UINavigationController is looking a blank page, even if has a view and some libraries.
Let me begin from the stracht:
In my AppDelegate, I'm setting tab bar controllers like this:
#interface MYAppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UITabBarController *tabBarController;
#end
And here is .m file:
#implementation MYAppDelegate
#synthesize window = _window;
#synthesize tabBarController = _tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
application.applicationSupportsShakeToEdit = YES;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UINavigationController *viewController1 = [[[MYMainViewController alloc] init] initWithNibName: #"MYMainViewController" bundle:nil];
UIViewController *viewController2 = [[[MYPageViewController alloc] init] initWithNibName:#"MYPageViewController" bundle:nil];
UIViewController *viewController3 = [[[MYSearchViewController alloc] init] initWithNibName:#"MYSearchViewController" bundle:nil];
UIViewController *viewController4 = [[[MYPersonViewController alloc] init] initWithNibName:#"MYPersonViewController" bundle:nil];
// Initialize tabBarController and add ViewControllers
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects: viewController1, viewController2,
viewController3, viewController4, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Then, here is MYMainViewController implementaion which is a UINavigationController:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#", [self navigationController]); // Logging null
}
My .xib file has a UINavigationController and and there is a view in it. Althought it, when I worked the app, there is blank page and untitled navigation bar. What am I doing wrong?
If I could see the content of my view, I want to navigate between two view controllers by using back button.
Any help or approach would be great for me.
Try to remove navigation controller from xib, so it only have view controller, then initialize navigation controller programatically:
UIViewController *tmpViewController1 = [[[YourViewController alloc] init] initWithNibName:#"YourViewController" bundle:nil];
UINavigationController *viewController1 = [[UINavigationController alloc] initWithRootViewController:tmpViewController1];

UINavigationController based app with FlipSideView with another UINavigationController

I'm trying to develop an app (game) with this architecture:
Main view is a naviagtioncontroller based with navbar hidden
in Main view I need a light info
button to show a options/credits
flipsideview
this flipsideview must have another
navigationcotroller with a right bar
button to a "Done" system button
The problem is that the flipsideview doesn't show the done button and it seems to show the Main navigation controller...
This is the code.
AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Main View (loaded from a XIB). Extract only of showInfo:
-(IBAction) showInfo:(id)sender {
FlipSideViewController *controller = [[FlipSideViewController alloc] initWithNibName:#"FlipSideView" bundle:nil];
controller.delegate = self;
controller.title = #"Info";
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
navController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
navController.navigationBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonItemStyleDone
target:controller action:#selector(done:)];
navController.navigationItem.rightBarButtonItem = doneButton;
controller.navController = navController;
[self presentModalViewController:navController animated:YES];
[doneButton release];
[controller release];
[navController release];
}
- (void)flipsideViewControllerDidFinish:(FlipSideViewController *)controller {
[self dismissModalViewControllerAnimated:YES];
}
FlipSideView. In the XIB I've only a blank view with outlet linked to the UIViewController view.
#protocol FlipsideViewControllerDelegate;
#interface FlipSideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
UINavigationController *navController;
}
#property (nonatomic,assign) id <FlipsideViewControllerDelegate> delegate;
#property (nonatomic,retain) UINavigationController *navController;
-(IBAction)done;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipSideViewController *)controller;
#end
}
Implementation file...
- (void)viewDidLoad
{
[super viewDidLoad];
self.navController.navigationItem.title = #"Pippo";
}
#pragma mark - User Methods
- (IBAction)done {
[self.delegate flipsideViewControllerDidFinish:self];
}
The result is:
Main View showing without navigation
bar
Click on info button
Flipsideview showing with animation
and navigation bar with title "Info" and not "pippo
and not "Done" button on the right...
Where am I wrong??
Don't you get two navigationBar with navigationItems on FlipsideViewController? I am fighting with this bug now.

Resources