So I am writing an app that will read a JSON feed. In my application:didFinishLaunchingWithOptions, I am writing some code to download the JSON string and store it into a local NSString variable. I will then pass that string into ListingsViewController (which is the Root VC of the NavigationController). When I print out the JSON data in ListingsViewController, it is showing me (null) which is making me think that viewDidLoad is loading before - which seems illogical?
So here is my application:didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Grab the feeds
NSURL *jsonURL = [NSURL URLWithString:#"http://www.shoofeetv.com/iphonexml/view/all_channels.json"];
NSString *jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL];
// Pass jsonData to the ListingsViewController
ListingsViewController *listingsViewController = [[ListingsViewController alloc] initWithNibName:#"ListingsViewController" bundle:nil];
listingsViewController.jsonData = jsonData;
[listingsViewController release];
// Display the navigation controller
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
My viewDidLoad method is as follows:
- (void)viewDidLoad {
self.navigationItem.title = #"Listings";
UIBarButtonItem *checkinButton = [[UIBarButtonItem alloc]
initWithTitle:#"Check In"
style:UIBarButtonItemStylePlain
target:self
action:#selector(switchView)];
self.navigationItem.rightBarButtonItem = checkinButton;
[checkinButton release];
NSLog(#"%#", self.jsonData);
[super viewDidLoad];
}
Please note that a common solution is to make sure that the App Delegate in MainWindow.xib must be connected to the File's Owner. Mine already is connected.
I will appreciate any help!
Thank you everyone.
well you are setting up a view controller with your code, but it is never shown within the navigation controller. you just set up a view controller, assign its jsonData a string and destroy the view controller immediately. I#m pretty sure the output you get is from a different view controller that you create in your main XIB.
what you want to do is create an empty navigation controller in your XIB and then do the following:
// Pass jsonData to the ListingsViewController
ListingsViewController *listingsViewController = [[ListingsViewController alloc] initWithNibName:#"ListingsViewController" bundle:nil];
listingsViewController.jsonData = jsonData;
[self.navigationController pushViewController:listingsViewController animated:NO];
[listingsViewController release];
// Display the navigation controller
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
this will actually display the view controller you created.
Also remember that when you deploy your application, you need to load your json-data asynchronously and handle network errors (apple will test your app under various network conditions)
Related
My First Question
DDMenuController(facebook split menu) Must be on RootviewController? it can not be on other viewController which we push on rootViewCotroller?
if answer is no then
Second Question
i am trying to make split viewController like facebook for that i am using this sample
https://github.com/devindoty/DDMenuController
now what i want to do is i dont want set DDMenuControl as rootviewcontroller in appdelegate in my rootcontrollers there are view buttons which push my all other ViewController
so what i want is from my rootViewController' Buttons i push another controller and then that view should get pushed and same time there should be DDMenuController too
so what will happen is on navigation bar there wont be back button there will be splitting screen button like facebook and from there i can go to another view controller
now let me tell you what i have achieved so far my rootViewController is getting displayed and then from there i push my other ViewController and on navigation bar splitting button is also getting displayed but its not working let me should you code to make this all clear
this is how i set my rootViewContoller in app delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
*)launchOptions
{
FirstPadViewController *mainController = [[FirstPadViewController alloc] init];
navController = [[UINavigationController alloc] initWithRootViewController:mainController];
self.window.rootViewController = navController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
so it get displayed with some buttons from where i can push my other viewController
this is how i push my other ViewController
- (IBAction)goToCamera:(id)sender {
AROverlayPadViewController *svController = [[AROverlayPadViewController alloc] init];
[self.navigationController pushViewController:svController animated:YES];
[svController release];
svController = nil;
}
so AROverlayPadViewController is getting pushed
and in AROverlayPadViewController's viewWillAppear this is what i do for achieving splitting screen like facebook
-(void)viewWillAppear:(BOOL)animated{
DDMenuController *rootController = [[DDMenuController alloc] initWithRootViewController:self];
LeftController *leftController = [[LeftController alloc] init];
rootController.leftViewController = leftController;
}
splitting button is getting displayed but when i press it is not working
now i really dont have any clue what to do any help will be highly appreciated
Answering the first question: actually it's a yes. This is how you do it, in the method that sends you to your nextScreen:
-(void) goToAnotherController {
OtherViewController *nextScreen = [OtherViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:nextScreen];
DDMenuController *menuController = (DDMenuController*)((AppDelegate*) [[UIApplication sharedApplication] delegate]).menuController;
[menuController setRootController:navController animated:YES];
}
I'm having trouble coding a button to go to the previous page. I was able to do it to go to the next page thinking if I did the same thing but changed it a bit it would work in reverse. Unfortunately, I come up with a lot of errors I can't resolve because it won't allow me to use the release function.
This is this the code that helps it to work going to the next page fine:
#import "ViewController.h"
#implementation ViewController
-(IBAction)btnClicked:(id) sender
{
//add the view of the view controller to the current View---
if (menuView==nil) {
menuView =
[[MenuView alloc] initWithNibName:#"MenuView"
bundle:nil];
}
[self.view addSubview:menuView.view];
}
-(void)dealloc {
[menuView release];
[super dealloc];
}
How do I do it so that a back button will go to the previous page though.
It's pretty simple, use this :
-(IBAction)back:(id) sender
{
[menuView.view removeFromSuperview];
}
But, I would suggest not using addSubview: for many views as it would be complex way to do. Use UINavigationController as #Paul.s suggested.
The way you are doing this is not quite correct and I would suggest doing some reading to get familiar with iOS programming.
Your program structure should be: create a navigation controller (2) to manage the stack of view controllers giving it a viewController (1) to act as it's root.
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// 1
FirstViewController *firstViewController = [[FirstViewController alloc] init];
// 2
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[firstViewController release]; firstViewController = nil;
self.window.rootViewController = navigationController;
[navigationController release]; navigationController = nil;
[self.window makeKeyAndVisible];
return YES;
}
This will display your first view controller inside a UINavigationController. A UINavigationController is responsible for managing a stack of UIViewController's and giving you UI to navigate back down the stack as well as calling all the appropriate presentation related methods on a UIViewController at the correct times e.g. viewDidLoad. You should check out The View Controller Programming Guide for lots of info
Then inside your first view controller you do something like this to respond to the button:
- (IBAction)buttonClicked:(id)sender;
{
SecondViewController *secondViewController = [[SecondViewController alloc] init];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release]; secondViewController = nil;
}
This creates a new view controller and pushes it onto the stack.
I've an iPhone app that is a navigation-based app.
The customer require to convert 60% of the app to be inside a global TabBar. (i.e. to include one tabbar in 60% from the app views)
So, what is the best practice to follow here?
Is it to include a TabBar using IB into the Window?
Or add change the navigation code cross the whole app and push a TabBarController instead of the regular ViewController?
Please provide me with ideas.
Thanks.
I used a new window-based application and put the following code:
The idea is that to create a UITabBarController and put on it the NavigationController instead of the ViewControllers.
And each navigationController will navigate to its own set of ViewContrllers.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController* tabBarContoller = [[UITabBarController alloc]init];
Cross1VC* cross1VC = [[Cross1VC alloc]initWithNibName:#"Cross1VC" bundle:nil];
cross1VC.title = #"Cross 1";
UINavigationController* crossNav = [[UINavigationController alloc]initWithRootViewController:cross1VC];
crossNav.title = #"Cross";
[cross1VC release];
Part1VC* part1VC = [[Part1VC alloc]initWithNibName:#"Part1VC" bundle:nil];
part1VC.title = #"Part 1";
UINavigationController* partNav = [[UINavigationController alloc]initWithRootViewController:part1VC];
partNav.title = #"Part";
[part1VC release];
NSArray* viewControllers = [NSArray arrayWithObjects:crossNav, partNav, nil];
[tabBarContoller setViewControllers:viewControllers animated:YES];
//tabBarContoller.delegate = [[SomeDelegateHandlerClass alloc]init]; // assign, not retain
[self.window addSubview:tabBarContoller.view];
//[tabBarContoller release]; // make instance variable and release in dealloc
[self.window makeKeyAndVisible];
return YES;
}
I have a tabbarcontroller with three tabs/viewcontrollers.
When I first start my app, with my ActivityIndicator set to be visible and animated - courtesy of interface builder - it works fine.
However when I click a button an internet window opens to Facebook in order to get the user's permission.
Once the Facebook part is taken care it returns to my app but the ActivityIndicator is not longer animated - it is still visible though, just frozen.
If I switch to another tab/viewcontroller and then come back to the tab/viewcontroller with the ActivityIndicator everything works fine.
Is there a way to refresh my ViewController so that I don't have to programmatically make the ViewController switch back and forth? Or any other suggestions?
/* I searched the forums and I saw a similar question. It appeared that there was a broken connection. Therefore I'll include the code where I add the ViewController (i.e., "controller" to my tabbarcontroller). */
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
controller = [[DemoAppViewController alloc] init];
controller.view.frame = CGRectMake(0, 20, 320, 460);
controller.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"movieAppBackground.jpg"]];
MyTabBarViewController *vc2 = [[MyTabBarViewController alloc] init];
SecondViewController *vc3 = [[SecondViewController alloc] init];
controller.title = #"Intro Screen";
vc2.title = #"Explore";
vc3.title = #"Send a Pic";
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = [NSArray arrayWithObjects:controller, vc2, vc3, nil];
self.theTBC=tbc;
[controller release];
[vc2 release];
[vc3 release];
[tbc release];
[self.window addSubview:tbc.view];
[self.window makeKeyAndVisible];
return YES;
}
whereever u have used NIB file to show with viewcontrollers u have to create them with initwithname
Example
SecondViewController *r=[[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
like this change whereever u have used nib file to create instance,
i meaned for all custom viewcontrollers u have created with NIB file
hey, I'm currently using the iPhone SDK and I'm having trouble passing an NSString through 3 views
I am able to pass an NSString between 2 view controllers but I am unable to pass it through another one. My code is as follows...
`- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)index`Path {
NSString *string1 = nil;
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"items"];
string1 = [array objectAtIndex:indexPath.row];
//Initialize the detail view controller and display it.
ViewController2 *vc2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:[NSBundle mainBundle]];
vc2.string1 = string1;
[self.navigationController pushViewController:vc2 animated:YES];
[vc2 release];
vc2 = nil;
}
in the "ViewController 2" implementations I am able use "string1" in the title bar by doing the following....
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = string1;
UIBarButtonItem *addButton = [[[UIBarButtonItem alloc]
initWithImage:[UIImage imageNamed:#"icon_time.png"]
style:UIBarButtonItemStylePlain
//style:UIBarButtonItemStyleBordered
target:self
action:#selector(goToThirdView)] autorelease];
self.navigationItem.rightBarButtonItem = addButton;
}
but I also have a NavBar Button on the right side that I would like to push a new view
- (void)goToThirdView
{
ViewController3 *vc3 = [[ViewController3 alloc] initWithNibName:#"ViewController3" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:NESW animated:YES];
vc3.string1 = string1 ;
[vc3 release];
vc3 = nil;
}
How do I pass on that same string to the third view? (or fourth)
What you have should work exceptthat you want to set the string in vc3 before you push it onto the stack to ensure it is present when the view and the nav bar draws. That is the way you have it in the vc2 that works.
However, as a matter of application design, it is poor practice to pass values directly between view controllers. Ideally, you want your view controllers to be standalone and able to function regardless of which other controller did or did not precede it. (This becomes really important when you need to resume an app back to the point where it was interrupted.) If make the view controllers interdependent your app will grow tangled and complex as it grows larger.
The best way to exchange data between views is to park the data in a universally accessible place. If it is application state information put it in user defaults or you can put in an attribute of the app delegate. If it is user data, then it should go in a dedicated data model object (which is either a singleton or accessible through the app delegate.)
You may find code sample from a question I asked earlier.