Accessing variable from different View Controllers - ios

I have developed an application using a TableView connected to a SQLite database with a search bar and everything works well.
I have a detail view controller that shows me infos about a clicked row. How can I pass a variable from AuthorVC.m to Details.m?
Partial code :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"prepareForSegue: %#", segue.identifier);
if ([segue.identifier isEqualToString:#"Details"])
// segue.identifier value here
{
Details *dv = segue.destinationViewController;
dv.labelText.text = author.title;
// author.title = dv.labelText.text ;
// your value to pass
[segue.destinationViewController setLabelText:author.title];
}
}

Do this:
Create property of variable in myDetails to pass data
Suppose i have NSString *strAuthoTitle in myDetails
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//Depending upon cell index pass your data differently
myDetails *objmyDetails = [myDetails alloc] initWithNib:#"myDetails" bundle:nil] //alloc your controller for navigation
objmyDetails.strAuthoTitle = [yourArrayofAuthorTile objectAtIndex:indexPath.row];
//Simarly other data can be passed
}
As u not mentioned that u were using storyboard so for that u need to create a segue between AuthorVC to Details controlers and use that segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{  
//NSLog(#"prepareForSegue: %#", segue.identifier);      
if ([segue.identifier isEqualToString:#"DetailsPass"]) // segue.identifier value here
{
objmyDetails = segue.destinationViewController;
objmyDetails.strText =lblText.text; // your value to pass
//[segue.destinationViewController setStrText:lblText.text];
}  
}

lets say you have 2 properties in your detailedVC strName and strDescription...
than before pushing the detailedVC in the stack, you could simple do something like:
detailedVCObject.strName = #"whatever";
detailedVCObject.strDescription = #"whatever";
hope it would help...

With story board
How pass data in seque ios5 storyboard uitableview to detail view
http://kurrytran.blogspot.in/2011/10/ios-5-storyboard-and.html
Without story board
For this you have to access varible in class one let see below example for example on click of table row you have to navigate on another view say root view. So for this define a variable in root view and access this view when you create object in didselect method of table.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
RootViewController *rvController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
//Increment the Current View
rvController.CurrentLevel += 1;
//Set the title;
rvController.CurrentTitle = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.navigationController pushViewController:rvController animated:YES];
[rv release]
}

Related

Segue executed before selecting a cell

I'm having an issue with my app.
I have 3 View controllers, let's name them Oil, App and Prop . Those 3 View Controllers are embed in Navigation controllers. And in those View Controllers I got 3 table view.
So from Up to Bottom and Left to Right :
Prop View Controller -> Prop Detail View Controller
Oil View Controller -> Oil Detail View Controller-> Web View Controller
App View Controller-> App Detail View Controller
So in the middle (Oil) Everything works fine, I click on a cell, and the Oil Detail View Controller is displayed, with the information I passed through my Segue.
OilViewController.m :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *sectionTitle = [aromaSectionTitles objectAtIndex:indexPath.section];
NSArray *sectionAroma = [tableData objectForKey:sectionTitle];
aromaNom = [sectionAroma objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"Detail" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Detail"]) {
OilDetailViewController *test = segue.destinationViewController;
test.aromaName = aromaNom;
test.botaniqueName.text = botaniqueName;
}
}
And I'm also performing Segue between Oil Detail View Controller and Web View Controller like this :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"webView"]) {
NSLog(#"Segue is catched");
WebViewViewController *webView = segue.destinationViewController;
webView.aromaUrl = _aromaName;
}
}
I click on the orange button and it displays the webview.
But now if I do the SAME thing in Prop or App it doesn't work properly.
For example in Prop Detail VC I got a Label that displays the Property selected, but it displays me the View Controller with the label containing the old selected property before displaying me the right property selected in the label. So I have 2 Prop Detail View displayed AND embed in my Navigation Controller.
I made a video of the simulator : http://videobam.com/VwgLx
The code in PropViewController.m :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *sectionTitle = [aromaPropSectionTitles objectAtIndex:indexPath.section];
NSArray *sectionProp = [propData objectForKey:sectionTitle];
propName = [sectionProp objectAtIndex:indexPath.row];
NSLog(#"prop name = %#", propName);
[self performSegueWithIdentifier:#"PropDetail" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"PropDetail"]) {
PropDetailViewController *propView = segue.destinationViewController;
propView.propStr = propName;
NSLog(#"PREPARE FOR SEGUE PROP VIEW CONTROLLER");
}
}
And in PropDetailViewController.m :
- (void)viewDidLoad {
[super viewDidLoad];
self.propLabel.text = _propStr;
NSLog(#"VIEW DID LOAD PROP DETAIL");
// Do any additional setup after loading the view.
}
Finally the logs :
Thanks in advance for your help, I'm stuck with this, and nobody in my team knows iOs .. So i'm alone with this !
So I finally managed to find a proper solution .. I still don't know why it works on Oil and causes problems on other views but still; here is the solution :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *sectionTitle = [aromaPropSectionTitles objectAtIndex:indexPath.section];
NSArray *sectionProp = [propData objectForKey:sectionTitle];
propName = [sectionProp objectAtIndex:indexPath.row];
NSLog(#"prop name = %#", propName);
[self performSegueWithIdentifier:#"PropDetail" sender:self];
}
Delete the method above. And do everything you do in this method in the prepareForSegue method instead :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"PropDetail"]) {
PropDetailViewController *propView = segue.destinationViewController;
NSIndexPath *indexPath = [self.propTableView indexPathForSelectedRow];
NSString *sectionTitle = [aromaPropSectionTitles objectAtIndex:indexPath.section];
NSArray *sectionApp = [propData objectForKey:sectionTitle];
NSString *name = [sectionApp objectAtIndex:indexPath.row];
propView.propStr = name;
}
}
Now it works fine ! But it's not logic that it works in a place, and doesn't in an other ..

Failed to push to a View Controller in iOS

I'm a very beginner to iOS development. I made a navigation application in iOS to view some details in another view when table view cell tap. I did the following code,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
LawyerViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"LawyerViewController"];
NSLog(#"%#",[self.myObject objectAtIndex:indexPath.row]);
dvc.lawyer = [self.myObject objectAtIndex:indexPath.row];
[self.navigationController pushViewController:dvc animated:YES];
}
This is going to the next view. But dvc.lawyer is not null here. It's null on Next View page.
Reading the Value in Next page
NSLog(#"%#",self.lawyer.firstName);
How can I fix this.
Thanks in Advance!
You are supposed to instantiate ViewControllers in another way, if you use storyboard segues. You need to implement prepareForSegue where you can Access the segues destinationViewController like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// reference to the destination view controller
LawyerViewController *vc = [segue destinationViewController];
// Pass any data
vc.lawyer = self.myObject[[self.tableView indexPathForSelectedRow].row]; // Not tested
}
}

Segue not passing data to destination

I have two table view controllers, one containing all the US states, the other presenting a list of data for the selected state. I have set up a segue in my main storyboard from the view controller (not the cell), and given it an identifier. For reasons beyond the scope of this post, I need to programmatically perform the segue without using the prepareForSegue method.
The source table view controller (AllStatesTableViewController) needs to execute the segue in the didSelectRowAtIndexPath method of the tableview.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
stateID = [statesDict objectForKey:cell.textLabel.text];
DetailTableViewController *destination = [[DetailTableViewController alloc] init];
stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateID andType:nil];
// at this point stateGauges is NOT nil
[destination setStateGauges:stateGauges];
[self performSegueWithIdentifier:#"sgShowStateDetail" sender:self];
}
The segue performs as intended in that it navigates to its destination, but stateGauges is nil in the destination table view controller. It is not nil in the source table view controller. stateGuages is declared as a property in DetailTableViewController. Obviously I am doing something wrong. Any suggestions?
Thanks! V
On your storyboard you need to choose to push your segue from your cell.
and use your prepareForSegue to pass data :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showDetail"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailTableViewController *detailTableViewController = segue.destinationViewController;
// Pass data here
destViewController.stateGauges = stateGauges;
}
}
Have a look here for more information
I ran into this before too. I found that when I let the storyboard handle the segue, it instantiates a new view controller. This is why stateGauges is nil, because you set stateGauges in your programmatically created view controller, not the one the storyboard created. If you won't use prepareForSeque, remove the segue from your AllStatesViewController to your DetailTableViewController in your storyboard. Then programmatically instantiate the storyboard, the view controller, setGauges, then present your view controller. Also, make sure you put "ShowStateDetail" in the "Storyboard ID" field, in the Identity section, on that DetailTableViewController in your storyboard.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
stateID = [statesDict objectForKey:cell.textLabel.text];
DetailTableViewController *destination = [[UIStoryboard storyboardWithName:#"yourStoryBoardName" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"ShowStateDetail"];
stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateID andType:nil];
[destination setStateGauges:stateGauges];
[self presentViewController:destination animated:YES completion:nil];
}

Table View View Controller Show Next View

Im working with table view controllers within story board.
I currently have one tableview controller embedded in navigation controller in my storyboard. This table view controller is linked to an ObjectiveC file.
Through code i can display another table view controller with the correct data using the tableView didSelectRowAtIndexPath method.
code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
WorkoutType *workoutType = (WorkoutType *)[self.fetchedResultsController objectAtIndexPath:indexPath];
WorkoutSetViewController *detailViewController = [[WorkoutSetViewController alloc] initWithWorkoutType:workoutType];
[self.navigationController pushViewController:detailViewController animated:YES];
}
But if i try to add another table view controller in storyboard, associate it with an objectiveC view controller file and connect the first TVC to it, That table view controller is not shown upon running the code.
I need to customise the second table view visually and have tried to use a segue push...as follows:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"show"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
WorkoutType *workoutType = (WorkoutType *)[self.fetchedResultsController objectAtIndexPath:indexPath];
//WorkoutSetViewController *detailViewController = [[WorkoutSetViewController alloc] initWithWorkoutType:workoutType];
WorkoutSetViewController *destViewController = segue.destinationViewController;
destViewController.workoutType = workoutType;
//[self.navigationController pushViewController:detailViewController animated:YES];
}
}
But when i run this code, the second table view controller doesn't even load although the application doesn't crash.
Whatever I am doing wrong must be simple, any help would be appreciated.
Thank You
Simple You have to navigate through below code. (No need to set storyboard when you working in same storyboard ViewController)
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexpath.row==0)//for first row click
{
WorkoutSetViewController *objWorkoutSetVC=[[WorkoutSetViewController alloc] i nitWithNibName:#"WorkoutSetViewController" bundle:nil];
[self.navigationController pushViewController:objWorkoutSetVC animated:YES];
}
else if(indexpath.row==1)//for second row click
{
//Put code in which screen you have to navigate
}
}
Do NOT Alloc init your new view controller. Use this code instead:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
WorkoutSetViewController *detailViewController = (WorkoutSetViewController *)[storyboard instantiateViewControllerWithIdentifier:#"coolID"];
[self.navigationController pushViewController:detailViewController animated:YES];
For MainStoryboard write your storyboard name and for coolID write your view controller id name which you set in your storyboard.

Pushing a view in Storyboard

I am trying to use Table Views and navigation controllers. This is the code I would use if I was using NIB files. This piece of code would work fine if I was using NIB files, but I decided to try storyboard -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (_webViewController == nil) {
self.webViewController = [[[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
_webViewController.entry = entry;
[self.navigationController pushViewController:_webViewController animated:YES];
}
I have created another scene in storyboard and have everything set up out there. When a user clicks a cell in this Table View they will be taken to that scene. This is what I wrote for the code but it is not right and I'm hopelessly stuck :( -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"articleView"]){
UINavigationController *navigationController = segue.destinationViewController;
WebViewController *controller = (WebViewController *)navigationController.topViewController;
controller.webView = self;
}
Answer - Answers 2 and 3 are both right
I had a very similar problem 2 days ago, with the user selecting the disclosure accessory on a row and wanting to invoke a segue. What worked for me:
In storyboard, create segue "articleView" from the entire tableView controller (not the cell) to the next viewController.
Add the following method to your tableViewController:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"articleView" sender:[self.tableView cellForRowAtIndexPath:indexPath]];
}
Just for you I also tested with tableView:didSelectRowAtIndexPath: and it works.
Enjoy,
Damien
If your table view is already embedded in a navigation controller (looks that way, from your first code snippet) then the destination view controller of your segue will be a WebViewController, not a navigation controller.
You can therefore have your prepareForSegue method pass the item directly across :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"articleView"])
{
WebViewController *controller = (WebViewController *)segue.destinationViewController;
RSSEntry *entry = [_allEntries objectAtIndex:[self.tableView indexPathForSelectedRow].row];
controller.entry = entry;
}
}
You may find this excellent two-part tutorial helpful
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1

Resources