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

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;
}
}

Related

Objective-C iPhone data between classes

Here is my situation. I have ViewController class A with a button that goes to TableViewController class B by doing the following.
- (void) goToClassB
{
ViewControllerB *viewController =
[[ViewControllerB alloc] initWithStyle:UITableViewStylePlain];
// Present view controller modally.
if ([self
respondsToSelector:#selector(presentViewController:animated:completion:)]) {
[self presentViewController:viewController animated:YES completion:nil];
} else {
[self presentModalViewController:viewController animated:YES];
}
}
I want to be able to have an array that can be accessed and edited by both class A and class B. How can I achieve this?
Create a Array variable in Class B like:
#interface classB:NSObject
{
NSMutableArray *arrayFromA;
}
#property (nonatomic, assign) NSMutableArray *arrayFromA;
Synthesize the variable.
And in this method pass the array like:
- (void) goToClassB
{
ViewControllerB *viewController = [[ViewControllerB alloc] initWithStyle:UITableViewStylePlain];
[viewController setArrayFromA:yourArray];
// Present view controller modally.
if ([self
respondsToSelector:#selector(presentViewController:animated:completion:)])
{
[self presentViewController:viewController animated:YES completion:nil];
}
else
{
[self presentModalViewController:viewController animated:YES];
}
}
Create a NSMutableArray in ViewControllerA and pass it to ViewControllerB after your allocation.
This can be achieve Creating NSMutableArray And And Make it in Property assign in one of the class
#property(nonatomic,assign) NSMutableArray *array;
I mention that you want edit by both so.You can use application delegation for sharing app level variable. Check this link.
Some code is here. In your app delegate class.
#interface YourDelegateClass:UIResponder
{
NSMutableArray *array;
}
#property (nonatomic, assign) NSMutableArray *array;
You can access that array from everywhere of your app class with this code
YourDelegateClass * delegate =[[UIApplication shareApplication]delegate];
yourclassa.array = delegate.array;
or yourclassb.array = delegate.array;
Note: your must alloc *delegate.array* on your prefer at class or your delegate.
Create NSMutable array in view1 set property
#property(nonatomic,assign) NSMutableArray *array;
Create same array in viewB and set property and
#property (nonatomic, assign) NSMutableArray *arrayB;
#Synthesize that
Now at the time call viewB set value of array of viewA to viewB like this
ViewControllerB *viewController = [[ViewControllerB alloc] initWithStyle:UITableViewStylePlain];
[viewController arrayB:array];
The simplest way would, just as others point out, be simply passing the array to B by setting a property, but one other option would be to let B have a weak back reference to A. Thus you're always using the same array. This could be useful if A and B are changing the array at the same time.
#interface ViewControllerA : UIViewController
#property (nonatomic, strong) NSArray *array;
#end
#interface ViewControllerB : UIViewController
#property (nonatomic, weak) ViewControllerA *viewControllerA;
#end
/* When you're creating the ViewControllerB, do this: */
...
viewController.viewControllerA = self;
...
/* Use the array (From ViewControllerB) */
- (void)doSomethingWithTheArray
{
self.viewControllerA.array = ...
}

Assign value to textfield firstview take of secondview

I have two views in my application: in main view there are input fields that the user must fill and a button connected to the second view. In the second view there is a table view, when the user selects a row automatically returns to the main view.
My problem is that when you return to the main view the values ​​of text fields are cleared.
Any solutions?
Thank you.
Second View header
#class MainViewController;
#interface ListaViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate>
{
UITableView *table;
UISearchBar *search;
MainViewController *child;
}
#property (nonatomic, retain) IBOutlet UITableView *table;
#property (nonatomic, retain) IBOutlet UISearchBar *search;
#property (nonatomic, retain) MainViewController *child;
- (IBAction)switchBack:(id)sender;
Second View Implementation:
-(IBAction)switchBack:(id)sender
{
child.selectedCountry = selectedCountry;
child.codiceComune = codiceComune;
[self.navigationController popViewControllerAnimated:YES];
}
First View:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
cityField.text = selectedCountry;
}
This not work!
-(IBAction)switchBack:(id)sender
{
MainViewController *controller = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated: YES];
[controller release];
}
It means you create new MainViewController, not return to previous.
Use this code instead
-(IBAction)switchBack:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}
P.S. It works if you go to the second vievcontroller same way, as you write in -(IBAction)switchBack:(id)sender
As a guess without code, you're probably emptying or initialising your text fields in viewDidLoad, viewDidAppear or viewWillappear - do it in your viewController init instead.

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

iPhone Xcode - Navigation Controller on second xib view?

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.