iPhone Xcode - Navigation Controller on second xib view? - iphone

Everything is fine, my navigation controller display's my 'Menu 1' item, but when i click it there appears to be a problem with the:
[self.navigationController pushViewController:c animated:YES]; line it doesn't connect to the break point in the myClass file. so I think i've not joined something? but unsure what?
My second view with the navigation controller doesn't have direct access to the AppDelegate so can't join it like I see in some tutorials.
1st view is just a button when clicked calls:
[self presentModalViewController:mainViewController animated:YES];
my second View 'MainViewController' header looks like:
#interface MainViewController :UITableViewController <UITableViewDelegate, UITableViewDataSource>
{
NSArray *controllers;
UINavigationController *navController;
}
#property (nonatomic, retain) IBOutlet UINavigationController *navControllers;
#property (nonatomic, retain) NSArray *controller;
Then I have my MainViewController.m
#synthesize controllers;
#synthesize navController;
- (void) viewDidLoad
{
NSMutableArray *array = [[NSMutaleArray alloc] init];
myClass *c = [[myClass alloc] initWithStyle:UITableViewStylePlain];
c.Title = #"Menu 1";
[array addObject:c];
self.Controllers = array;
[array release];
}
implemented numberOfRowsInSection and cellForRowAtIndexPath
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
myClass *c = [self.controllers objectAtIndex:row];
[self.navigationController pushViewController:c animated:YES]; // doesn't load myClass c
// [self.navController pushViewController:c animated:YES];
}
Also in Interface Builder I dragged a Navigation Controller onto my new XIB and changed the Root View Controller class to MainViewController and also connected the File Owner connector to the Navigation Controller to connect the navController Outlet.
Thanks for you time.

myClass.h
#import "SecondLevelViewController.h" //This inherts UITableViewController
#class myClass;
#interface myClass : SecondLevelViewController
{
NSArray *list;
myClassDetail *detail;
}
#property (nonatomic, retain) NSArray *list;
myClass.m
#import "myClass.h"
#import "myClassDetail.h"
#import "NavAppDelegate.h"
#implementation myClass
#systjesize list;
- (void) viewDidLoad
{
NSArray *array = [[NSArray alloc] initWithObjects:#"test1",#"test2",nil];
self.list = array;
.. .. ..
//I can't get a break point at this point or in any of the other methods
}
So not getting a break point to hit in this page tells me I've missed sometihng. With this being a seperate XIB file from the MainWindow.XIB, I don't have access to the App Delegate.
So really I need to know how to wire Navigation Controller to a second view XIB file when I don't have a App delegate in the interface builder. All the tutorials show the navigation controller being connected to this app delegate.
The program complies file and runs, I get the 1st 'Menu 1' in the list but then when I try and re populate the same navigation list with my new myClass menu items 'test 1', 'test 2'
it doesn't hit the event viewDidLoad.

Related

How to pass data between not neighbor view controllers in Storyboard

I've stuck in the problem.
I have a storyboard with several view controllers.
What I need to do is:
I need to pass an array from FirstViewController to SecondViewController (they are not neighbors and are not connected via segue) where PikerView will upload the array. After that the picked result should be passed to ThirdViewController.
I have tabbed applicateion where FirstViewController and SecondViewControllers are connected to Tab Bar View Controller and ThirdViewController is connected with SecondViewController via Push Segue.
See how I try to pass data form First to Second
CategoryExpencesViewController.h
#import <UIKit/UIKit.h>
#import "AddCategoryViewController.h"
#import "CategoryPickerViewController.h"
#interface CategoryExpencesViewController : UITableViewController <AddCategoryViewControllerDelegate>
#property(nonatomic, weak) IBOutlet UIBarButtonItem *editButton;
#property(nonatomic, strong) NSMutableArray *categories; //list of category items
#property(nonatomic, strong) NSMutableArray *listOfCategories; //list of category names
CategoryExpencesViewController.m
-(void)updateArray
{
CategoryPickerViewController *controller = [[CategoryPickerViewController alloc]init];
controller.categoryList = [[NSMutableArray alloc]init];
controller.categoryList = listOfCategories;
NSLog(#"%d", [listOfCategories count]);
NSLog(#"%d", [controller.categoryList count]);
}
I think you need this
Use your's Push Segue.
segue.sourceViewController (or self) will point at SecondViewController.
segue.sourceViewController.tabBarController will point at Tab Bar Controller.
From Tab Bar Controller you will find your's FirstViewController.
I suppose you would have solved it, but i post this just for the record:
Wrap the array into a class, and make it have a static construction method:
Wrapper.h:
#property (nonatomic, strong) NSMutableArray* array;
+(Wrapper*)createArray;
Wrapper.m:
+(Wrapper*)createArray{
static Wrapper* instance = nil;
if (instance == nil) {
instance = [[Wrapper alloc] init];
//Your initialization code for the array
}
return instance;
}
Then, in your FirstViewController:
-(void)updateArray{
CategoryPickerViewController *controller = [[CategoryPickerViewController alloc]init];
controller.categoryList = [[NSMutableArray alloc]init];
controller.categoryList = [[Wrapper createArray] array];
NSLog(#"%d", [listOfCategories count]);
NSLog(#"%d", [controller.categoryList count]);
}
As this is the first call to Wrapper, the array is generated.
Then in your SecondViewController, when you call:
secondView.categoryList = [[Wrapper createArray] array];
and you obtain the same array as in FirstViewcontroller.
have you thought of NSUserDefault try it and you can also create a instance global variable in AppDelegate class and access it by creating an instance of AppDelegate in any other ViewController but i think NSUserDefault is the best option from all.

UI is not updating while sending data from another view controller on UITabBar?

i am using UITabBar to display two viewControllers, firstViewController is a uiview and secondViewController is a table view. what my need is when i clicked the second view table cell, the value should be updated on UILabel of firstViewController.
my code is here,
In secondviewcontroller.h
#interface firstviewcontroller {
NSMutableArray *stationnamestobepassed;
}
#property (nonatomic, retain) NSMutableArray *stationnamestobepassed;
#end
In secondviewcontroller.m declare this
#implementation firstviewcontroller
#synthesize stationnamestobepassed;
-(void) someaction{
stationnamestobepassed = [NSMutableArray
arrayWithObjects:#"string1",#"string2",#"string3"];
secondviewcontroller = [[secondviewcontroller alloc]initWithNibName:#"NIbName"
Bundle:nil];
secondviewcontroller.stationnamespassed = self.stationnamestobepassed;
//i am not pushing the view controller.
}
#end
In firstviewcontroller.h declare this
#interface secondviewcontroller {
NSMutableArray *stationnamespassed;
}
#property (nonatomic, retain) NSMutableArray *stationnamespassed;
#end
In firstviewcontroller.m declare this
#implementation secondviewcontroller
#synthesize stationnamespassed;
-(void)viewWillAppear:(BOOL)animated
{
//stationNameDisplay is a uilabel
stationNameDisplay.text=[stationnamespassed objectAtIndex:0];
NSLog(#"station name %#",[stationnamespassed objectAtIndex:0]);
}
-(void) dealloc{
[stationnamespassed release];
[super release];
}
#end
problem is , value is not updating and it gives NULL. but i tried with pushing the first vie and it works. actually i don't want to push that view controller because i was already exist on tab.
your view will appear called out when you select the tab. while this line makes a new object of that controller, not that of tab controller.
secondviewcontroller = [[secondviewcontroller alloc]initWithNibName:#"NIbName"
Bundle:nil];
to do what you want. you will have to do some thing like this
UINavigationController* navController = [[self.tabBarController viewControllers] objectAtIndex:/*your tab index on which desiredControllerResides*/];
NSArray* viewControllers= [navController viewControllers];
for(UIViewController *theController in viewControllers)
{
if([theController isKindOfClass:[secondviewcontroller]])
{
theController.stationnamespassed = self.stationnamestobepassed;
//i.e this line of your code secondviewcontroller.stationnamespassed = self.stationnamestobepassed;
}
}

Pass a value to the text field of the first view

I have two views with navigation controller: first view, there are empty text fields while the second view is a table view where the user can select a row. At the touch of a row there is an action that sets a value to a text field of the first view. Unfortunately when I go back to the first view field is not set.
This is my code:
FirtViewController.h
#interface FirstViewController : UIViewController
{
UITextField *firstField;
UITextField *secondField;
}
#property(nonatomic, retain) IBOutlet UITextField *firstField;
#property(nonatomic, retain) IBOutlet UITextField *secondField;
#property(copy) NSString *selectedRow;
-(IBAction)showTable:(id)sender
FirstViewController.m
#import "FirstViewController.h"
#import "AppDelegate.h"
#import "SecondViewController.h"
#implementation FirstViewController
#synthesize .....
.............
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.firstField.text = selectedRow;
}
-(IBAction)showTable:(id)sender
{
SecondViewController *controllerSecond = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:controllerSecond animated:YES];
}
SecondViewController.h
#class FirstViewController;
#interface ListaViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate>
{
UITableView *table;
UISearchBar *search;
FirstViewController *controller;
}
#property (nonatomic, retain) FirstViewController *controller;
SeconViewController.m
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectedRow = [tableData objectAtIndex:indexPath.row];
controller.selectedRow = selectedRow;
[self.navigationController popViewControllerAnimated:YES];
}
Based on your code above, you never set the connection in secondViewController back to first
You probably need something like this:
-(IBAction)showTable:(id)sender
{
SecondViewController *controllerSecond = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[controllerSecond setController:self]; //this sets the reference back
[self.navigationController pushViewController:controllerSecond animated:YES];
}
What you need to use is delegate. It is very commonly used pattern in Object-C. Check out my answer to this SO post. Let me know if you still need code after.
I'm not certain I fully understand what you mean, but why don't you creating an NSString containing the value you need in the SecondViewController. That way you can do something like this when you set up the SecondViewController.
SecondViewController *nextView = [[SecondViewController alloc] init];
nextView.myNSString = #"Value you need in the next view";
Then in SecondViewController.h you'll be able to access the NSString like so:
#NSLog(#"%#", self.myNSString);
The main thing you are missing is the Value passing between views. You are not using any object in any of the view that is passing the value to another view. Like, If you want to pass a text from FirstViewController to SecondViewController. You Can do it as follwos.
NSString *textToPass = self.firstField.text;
In Your SecondViewController there need to be a string object say passedText. When you create object of secondViewController in firstViewController, Do it as follows:
SecondViewController *controllerSecond = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
controllerSecond.passedText = textToPass;
[self.navigationController pushViewController:controllerSecond animated:YES];
Now Wherever you want to show the text of first screen, just use "passedtext" String.
Hope it Helps.
:)
===============================================
In your code you may try the followinf modification:
NSString *selectedRow = [tableData objectAtIndex:indexPath.row];
controller = (FirstViewController *)[self.navigationController topViewController];
controller.selectedRow = selectedRow;
[self.navigationController popViewControllerAnimated:YES];
It Will resolve your problem forsure.

Adding a TableViewController to an existing project

I have an existing TableViewController as follows
// TableViewController.h
#interface TableViewController : UITableViewController { NSArray *dataArray; }
#property (nonatomic, retain) NSArray *dataArray;
And a navAppDelegate - to be specific:
// navAppDelegate.h
#import <UIKit/UIKit.h>
#interface navwAppDelegate : NSObject
<UIApplicationDelegate, UINavigationControllerDelegate> {
UIWindow *window;
IBOutlet UINavigationController *navigationController;}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) UINavigationController *navigationController;
// navAppDelegate.m
#import "navAppDelegate.h"
#implementation navigationtableviewAppDelegate
#synthesize window, navigationController;
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
[window makeKeyAndVisible];
[window addSubview:[navigationController view]];
}
Now, I simply added the files to an existing project, except I put the content of (void)applicationDidFinishLaunching{} in a (void)viewDidLoad{} since it's a view from now on and not a window (right?). It doesn't work and my guess is that I have to change all the window calls from above to a view? What am I making here fundamentally wrong?
I'm making a call from
// StartOffHere.m
- (void)LetsGoButtonTouched {
navAppDelegate *newview = [[navAppDelegate alloc] initWithNibName:nil bundle:nil]; // I get a SIGABRT here
[[self navigationController] pushViewController: newview animated: YES];
}
- (void)LetsGoButtonTouched {
TableViewController *tableViewController = [[TableViewController alloc] init];
[[self navigationController] pushViewController:tableViewController animated: YES];
}
Try that. Is that what you wanted to happen?
If so, what I have done is created a new instance of your table view controller and pushed that. In your original code, you were trying to push on the app delegate which cannot be done; the app delegate is not a view controller. TableViewController, your subclass of UITableViewController, is though, so you can use this for the pushViewController: method - and the table view will appear on screen.
Thanks Benjamin. Excellent. But it didn't work quite that way though - after two hard days I managed it to run. For those who are interesed, here's what I did:
If you want to add an existing TableViewController with a NavigationController you'll only need the TableViewController and the DetailViewController files. Forget the AppDelegate.
Do twice new file -> Subclass and copy your existing code into identical TableViewController .h/.m/.xib - and DetailViewController .h/.m/.xib respectively.
When you make the method call you have to integrate both the TableViewController and the NavigationController - like this:
- (void)LetsGoButtonTouched {
TableViewController *tvc = [[[TableViewController alloc] init] autorelease];
UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:tvc]autorelease];
[self presentModalViewController:navigationController animated:YES];
By the way, this question gave me the hint:
Add a UINavigationBar to a UITableViewController without a UINavigationController

Access Delegate Data

Hello i'm trying to make a simple ios app with tabs and navigation .
in the delegate i have the following type:
BlogRss * _currentlySelectedBlogItem;
with this property:
#property (readwrite,retain) BlogRss * currentlySelectedBlogItem;
and i'm trying to get his data with two other classes, one is a table view with the data and the other will show the data;
in both classes i have declared the following:
#class NewsAppDelegate;
NewsAppDelegate * _appDelegate;
#property (nonatomic, retain) IBOutlet _NewsAppDelegate * appDelegate;
#synthesize appDelegate = _appDelegate;
ofter "touching" the cell in the table view i wrote this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[self appDelegate] setCurrentlySelectedBlogItem:[[[self rssParser]rssItems]objectAtIndex:indexPath.row]];
// Navigation logic may go here. Create and push another view controller.
// [[self appDelegate] loadNewsDetails];
NewsDetailViewController *detailViewController = [[NewsDetailViewController alloc] initWithNibName:#"NewsDetailViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
when i'm writing in the other class:
NSLog(#"%#",self.appDelegate.currentlySelectedBlogItem);
i'm getting null.
clearly i'm doing something wrong, but i don't know what...
The problem is likely that this line is returning null:
[[[self rssParser]rssItems]objectAtIndex:indexPath.row]
Code is easier to debug when you don't nest so many sentences.
You can access your delegate from anywhere because UIApplication is a singleton, you don't need to keep a reference as you do with self.appDelegate. Example:
(NewsAppDelegate *)[[UIApplication sharedApplication] delegate];
Or just do as Jennis suggest, who is a faster typer than me, and remove the IBOutlet. :P
When you do
NewsAppDelegate * _appDelegate;
#property (nonatomic, retain) IBOutlet _NewsAppDelegate * appDelegate;
#synthesize appDelegate = _appDelegate;
The result is the same if you skip the first line, because the runtime creates it for you.
See Question about #synthesize. And I guess _NewsAppDelegate is really NewsAppDelegate (no underscore).
Please do as follow.
//Your Header File
#import "YourAppDelegate.h"
#interface YourViewController : UIViewController
{
YourAppDelegate *appDelegate;
}
#property(nonatomic,retain) YourAppDelegate *appDelegate;
#end
//Your Implementation file
#implementation YourViewController
#synthesize appDelegate
- (void)viewDidLoad {
self.appDelegate = (YourAppDelegate*) [[UIApplication sharedApplication] delegate];
}
#end
After declaring as above you will have access of appDelegate anywhere in your view controller.
Hope it helps.