passing data between tableView and another view in objective c - objective-c

I want to pass selected row's text to another view's label. But this not work. Not pushing second view. How can I solve this problem?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SecondViewController *detailViewController = [[SecondViewController alloc] initWithNibName:#"SecondView" bundle:nil];
// ...
// Pass the selected object to the new view controller.
NSUInteger row2 = [indexPath row];
NSLog(#"rowden %i",row2);
denemelik=row2;
NSLog(#"kontrol %i",denemelik);
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController.stringdir= [ws2.CustomerName objectAtIndex:[indexPath row]];
NSLog(#"hoff %#", [ws2.CustomerName objectAtIndex:[indexPath row]]);
NSLog(#"kontrol2 %#",ws2.CustomerName);
[detailViewController release];
}
in my secondViewController.m viewDidLoad I set the 'stringdir' to label's text:
enyakinfirma.text = stringdir;

You just need to swap this 2 line of codes around
detailViewController.stringdir= [ws2.CustomerName objectAtIndex:[indexPath row]];
[self.navigationController pushViewController:detailViewController animated:YES];
You should set the value before calling the navigationController. At least that's what i am doing.

Related

Call Multiple ViewController with UIViewController

In my project I have tableView with 10 cells. And in didSelectRowAtIndexPath all cells have multiple ViewController (files) so, my didSelectRowAtIndexPath looks like
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0) {
CallViewController *viewc = [[CallViewController alloc] initWithNibName:#"CallViewController" bundle:nil];
[self.navigationController pushViewController:viewc animated:YES];
}else if(indexPath.row == 1) {
BirthdayViewController *viewc = [[BirthdayViewController alloc] initWithNibName:#"BirthdayViewController" bundle:nil];
[self.navigationController pushViewController:viewc animated:YES];
}
so I don't want these conditions
I want my code be clean
I would suggest you to have an array that contains the Class object of your class and then create object and push like
//view did load
mutableArr = [[NSMutableArray alloc] init];
[mutableArr addObject:[CallViewController class]];
[mutableArr addObject:[BirthdayViewController class]];
....
....
Then in your
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row < [mutableArr count]) {
Class *obj = [mutableArr objectAtIndex:indexPath.row];
UIViewController *controller = [[objc alloc] initWithNibName:NSStringFromClass(obj) bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
}
}
OR if this is looking more weird then you can do like this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *controller = nil;
switch(indexPath.row) {
case 0:
controller = [[CallViewController alloc] initWithNibName:#"CallViewController" bundle:nil];
break;
case 1;
controller = [[BirthdayViewController alloc] initWithNibName:#"BirthdayViewController " bundle:nil];
break;
}
[self.navigationController pushViewController:controller animated:YES];
}
What is your underlying data model for tableview? If you could add additional attribute as ViewController Class Name you could do something like
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *row = [rowData objectAtIndex:indexPath.row];
Class viewControllerClass =
NSClassFromString([row objectForKey:#"viewControllerClassName"]);
//Default VC init looks for nib file named as VC afaik, if not, you could
//add another attribute with init selector name
UIViewController *viewController =
[[viewControllerClass alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
You can create array of strings corresponding to file names and use NSClassFromString function to allocate view controllers
NSArray *viewControllers = [NSArray arrayWithObjects:#"VC1", #"VC2", #"VC3", nil];
id viewController = [[NSClassFromString([viewControllers objectAtIndex:indexPath.row]) alloc] initWithNibName:[viewControllers objectAtIndex:indexPath.row] bundle:nil];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];
You can do this:
Add all your classes to NSArray, and select the correct class by the indexPath.row.
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray * conrollersClasses =#[[CallViewController class],[BirthdayViewController class]];
UIViewController *controller = [[conrollersClasses[indexPath.row] alloc] init];
[[self navigationController] controller animated:YES];
}

Tablecell click short delay

When I click on table cell, there's a short delay of 1-2 second before it loads the next view. I've seen some apps that show an activity indicator during that time and that's what I'd like to do. I've added one like this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
spinner.frame = CGRectMake(200,200,200,200);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = spinner;
[spinner startAnimating];
[spinner release];
VenueViewController *vviewcontroller = [[VenueViewController alloc] initWithNibName:#"VenueViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:vviewcontroller animated:YES];
[vviewcontroller release];
vviewcontroller = nil;}
however this also appears with a delay, and just before the next view is showing. It seems the app freezes for 1-2 seconds after clicking on the table cell so it doesn't even show the activity indicator.
I think the secret is that you should call load method using a performSelector method. Another tip is hiding or showing the activity so it won't consume time this operation.
So this could be a pseudocode of that
Inside your ViewController class definition:
IBOutlet UIActivityIndicatorView *spin; // created in view and hidden
In your implementation...
-(void) load{ // your code
VenueViewController *vviewcontroller = [[VenueViewController alloc] initWithNibName:#"VenueViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:vviewcontroller animated:YES];
[vviewcontroller release];
vviewcontroller = nil;
spin.hidden=YES;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
spinner.hidden=NO;
[self performSelector:#selector(load) withObject:nil afterDelay:0];
}
Hope it helps.

iOS duplicate/zombie view controller being referenced

I have a MainWindow class that is built from a nib and set up as follows:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
MainViewController *mainView = [[MainViewController alloc] initWithNibName:#"MainViewController"
bundle:nil];
if(!mainView)
{
return;
}
naviController = [[UINavigationController alloc] initWithRootViewController:mainView];
[naviController setToolbarHidden:YES];
[[naviController navigationBar] setTintColor:[UIColor blackColor]];
[[naviController toolbar] setTintColor:[UIColor blackColor]];
[self.window setRootViewController:naviController];
[self.window makeKeyAndVisible];
}
This works and correctly displays the MainViewController, but when I try to scroll down in the MainViewController's table view it throws an EXC_BAD_ACCESS. Apparently UIKit is referring to a second MainViewController that was built in [self.window makeKeyAndVisible]; I can't figure out why it is referencing that over the one I passed into initWithRootViewController:mainView.
Here are the two MainViewControllers. The first one I initialize, the second is created in makeKeyAndVisible.
Here is the second MainViewController being called as a zombie.
Any ideas on why this is happening?
As requested:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MainViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainViewCell"];
int i = [indexPath row];
NSLog(#"%d\n",i);
if (cell == nil) {
// Create a temporary UIViewController to instantiate the custom cell.
UIViewController *temporaryController = [[UIViewController alloc] initWithNibName:#"MainViewCell" bundle:nil];
// Grab a pointer to the custom cell.
cell = (MainViewCell *)temporaryController.view;
// Release the temporary UIViewController.
[temporaryController release];
}
[[cell icon] setImage:[UIImage imageNamed:[[moduleXMLList objectAtIndex:i] objectForKey:#"thumbnail"]]];
[[cell title] setText:[[moduleXMLList objectAtIndex:i] objectForKey:#"title"]];
[[cell description] setText:[[moduleXMLList objectAtIndex:i] objectForKey:#"description"]];
return cell;
}
The problem was that I was using File's Owner as a MainViewController while having a second UIViewController under Objects. This is wrong, and so once I got rid of the Object and just used File's Owner it worked like a charm.

passing data between firstviewcontroller's table view and secondviewcontroller of tabBarController

I want to do pass selected row text from first tab's table view to second tab's view label. I try this but it not work :S stringdir is a nsstring
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SecondViewController *detailViewController = [[SecondViewController alloc]initWithNibName:#"SecondView" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController.stringdir= [ws2.CustomerName objectAtIndex:[indexPath row]];
NSLog(#"şişşşt %# ", detailViewController.stringdir);
[detailViewController release];
}
Move detailViewController.stringdir = ... before you push the view controller to nav controller stack.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SecondViewController *detailViewController = [[SecondViewController alloc]initWithNibName:#"SecondView" bundle:nil];
detailViewController.stringdir= [ws2.CustomerName objectAtIndex:[indexPath row]];
NSLog(#"şişşşt %# ", detailViewController.stringdir);
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}

Is this the best way to dynamically load a UIViewController object based on item selection?

My root view contains three sections in a table view. Depending on which section is selected a corresponding view controller will be popped onto the view stack. The following didSelectRowAtIndexPath method is from my code and it works as I expect, but I was wondering if this is the correct/most elegant way to do it. I'm an Objective-C newcomer so I'm not sure if I should be intitializing the viewController to nil first.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *viewController = nil;
if (indexPath.section == 0) {
viewController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
}
else if (indexPath.section == 1) {
viewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
}
else if (indexPath.section == 2) {
viewController = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
}
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
}
You could do this in a swtch() statement, but otherwise, I think this is good. The only other change would be to check for a viewController before pushing:
if (viewController != nil) [self.navigationController pushViewController...