I have a HomeTableViewController which consists of two sections. When you click on ANY cell, it directs the user to the DetailsViewController. The DetailsViewController has 2 labels. One in the cell number, the other is the due date. To direct my cell to my details view controller I have the following code: This is in my HistoryTableViewController.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// HistoryDetailsViewController *HDV = [self.storyboard instantiateViewControllerWithIdentifier:#"HistoryDetails"];
// [self.navigationController pushViewController:HDV animated:YES];
NSLog(#"index path section--%i",[indexPath section]);
[self performSegueWithIdentifier:#"Push" sender:indexPath];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"Push"]) {
HistoryDetailsViewController *detailVC=(HistoryDetailsViewController*)segue.destinationViewController;
}
}
Now that I'm able to access my DetailsViewController, I want to control its labels. I want to be able to modify the labels ACCORDING TO THE SECTION OF THE CELL I TAPPED ON.
However when I try something like
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"Push"]) {
HistoryDetailsViewController *detailVC=(HistoryDetailsViewController*)segue.destinationViewController;
detailVC.labelCellNum.text = #"Cell test";
detailVC.labelDueDate.text = #"Date Test";
}
}
I can't even modify the label's text using this code. I don't understand.
All help is appreciated, thanks in advance.
The way I would do it would be to have a property for each string you'd like to use in the detail view: (declared in .h)
#property (nonatomic, strong) NSString *stringOne;
Then in the prepareForSegue, I would assign a certain value to it:
[detailVC setStringOne:#"Some string"];
And in the viewDidLoad method of the Detail VC, I'd set that string somewhere I want to use it:
[self.labelCellNum setText:self.stringOne];
Related
i have a tableview and i want to when I touch on the cells to be navigate to the editViewController and when I Long touch (touch and wait) on the cells to be navigate to the DetailsViewController.
I got the answer to this question here.
now i have another problem, i use following code to pass selected row to detailViewContoler
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if([[segue identifier] isEqualToString:#"ContectDetails"])
{
//get selected contact
NSManagedObject *selectedContact=[contacts objectAtIndex:[[self.tableView indexPathForSelectedRow] row]];
//pass selected contact to MyContactAppViewController for editing
ContactDetailsViewController *destViewcontroller=segue.destinationViewController;
destViewcontroller.contact=selectedContact;
//contact is my core data object
}
}
now i need to creat a modal segue and set segue identifier to "ContectDetails" in long press method.
Create a segue in storyboard between your table view's view controller and the ContactDetailsViewController and name it in the attributes inspector (let's say you name it 'ContactDetailsModalSegue').
Then in the gesture recognizer handler method you can call the segue like this:
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer {
[self performSegueWithIdentifier:#"ContactDetailsModalSegue"
sender:self];
}
In this case self should be the view controller that your table view resides in. If you are handling the long press inside the table view cell class, then you should keep a weak reference to the table view's view controller and refactor accordingly:
In your table view cell's .h file include a pointer to the parent vc:
#property (weak, nonatomic) UIViewController *vc;
Make sure you pass a reference to the cell when you set it up in the table view delegate:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
cell.vc = self; //Assuming your datasource is in the view controller file (adjust if necessary)
}
and finally in the tableview cell's .m file, use the pointer to the vc to call the segue:
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer {
[self.vc performSegueWithIdentifier:#"ContactDetailsModalSegue"
sender:self];
}
Update:
In order to pass a reference to the data that was used to populate the table view cell to the destinationViewController, you can do the following:
First, ensure that the data is stored in a model object in your custom table view cell subclass .h file. For this example I am using an NSManagedObject because thats what is in your question, but others reading this can swap this out with any model object (e.g. an NSObject subclass):
#property (strong, nonatomic) NSManagedObject *managedObject;
Note that in the performSegueWithIdentifier: method call you are passing a reference to self as the sender parameter. The object you specify for the sender parameter will be passed as an argument to the - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender method. This enables you to retrieve the public property you just added to your custom table view cell, like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
//Verify segue identifier
if([[segue identifier] isEqualToString:#"ContactDetailsModalSegue"])
{
//Protect yourself from unrecognized selector errors in case you reuse this segue
if ([sender isKindOfClass:[YourCustomTableCellClass class]] &&
[segue.destinationViewController respondsToSelector:#selector(setContact:)]) {
//get selected contact
NSManagedObject *selectedContact= (YourCustomTableCellClass *)sender.managedObject;
//pass selected contact to ContactDetailsViewController for editing
ContactDetailsViewController *destViewController= segue.destinationViewController;
destViewController.contact = selectedContact;
}
}
}
replace [self.navigationController pushViewController:detailView animated:YES]; with [self.navigationController presentModalViewController:detailView animated:YES completion:nil]; in the method
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
}
I am trying to push data from a UITableViewCell into another view controller. I have tried two separate ways, instantiateViewControllerWithIdentifier and also PrepareForSegue. In both instances the ViewController loads correctly but the data is not being passed across (either null, or the first array value).
Here is my instantiateViewControllerWithIdentifier method, when I log the variable within my ViewController it just returns null.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *testNumber = [jobNumberArray objectAtIndex:indexPath.row];
NSLog(#"Job is... %#",testNumber);
StandardInfoViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"StandardInfoViewController"];
controller.JobNr = [jobNumberArray objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
Prepare For Segue
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"Details" sender: self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"Details"]){
StandardInfoViewController *controller = (StandardInfoViewController *)segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
controller.jobNumber = [jobNumberArray objectAtIndex:indexPath.row];
}
}
When I use the prepareForSegue call I get the first row of my Array, which I understand because it doesn't know the cell, but I don't know how to identify the Cell within the prepareForSegue call.
I hope this makes sense, and any help or pointers would be greatly appreciated.
Thanks
If you drag the segue FROM the tableView-cell in the storyboard, you will then get the cell itself as parameter sender.
then you can use tableView indexPathForCell:sender to get the actual index of the selected cell. Then just fetch your object normally.
I.e. you will not need to implement didSelectRowAtIndexPath
If you still want to use didSelectRowAtIndexPath, just pass the cell as the sender parameter manually. I.e:
[self performSegueWithIdentifier:#"Details"
sender:[self.tableView cellForRowAtIndexPath:indexPath]]
Although your first version with instansiateViewController should work, judging by your code.
Another pattern is to subclass the cells themselves, and let them have a property that is the object that they want to display. Then you can just fetch the object directly from the cell without calling the data-array itself.
Is this what you want?
This is how you identify Cell in prepareForSegue method.
**UITableViewCell *cell=[myTable cellForRowAtIndexPath:path];**
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"Details"]){
StandardInfoViewController *controller = (StandardInfoViewController *)segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
**UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];**
controller.jobNumber = [jobNumberArray objectAtIndex:indexPath.row];
}
}
I am using UITableViewController and on selection of row from the list i want to open another scene and send the info of the selected row. I got one link and i followed that and also i attched say Segue1 to segue2 in push mode. but when i am executing it is throwing error for no such segue associated with segue1.
below is the code for Row Selection:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"index is %ld",(long)indexPath.row );
[self performSegueWithIdentifier:#"Put_Controller" sender:indexPath.self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"Put_Controller"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = _objects[indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
Don't forget to set storyboard segue identifier:- Put_Controller
have you checked that the name is set properly between the scenes?
Actually i was not setting the identifier in the attributes Inspector and that i got from the link attached and now its working ::http://prateekvjoshi.com/2013/11/02/how-to-trigger-a-segue-programmatically-in-ios/
I want to create table, and when click cell in table , the content will display in another view. Each of table has different design. How do I do that.
I don't enough to post image, you can see in this link. thanks.
Use this delegate method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"InstructionToSection" sender:nil]; //"InstructionToSection" is seque name
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
InstructionSectionViewController * instructSection = [segue destinationViewController]; // InstructionSectionViewController is ur next viewcontroller. 1st u need to import your destination viewcontroller in header
instructSection.SelectedItem = #"Ur Passing value"; // selectedItem should be declare in InstructionSectionViewController as property, need to synthesize
}
For more detail refer to this link
Here's my problem. I have data being passed into the 'second view controller' by mySQL which currently works great. But when I select on any of the from (UITableView) cells, I am currently not able to open a new view to show the data.
I believe the code issue is with
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
detailedViewController *productinfo = [self.storyboard instantiateViewControllerWithIdentifier:#"productDetails"];
//Retrieve current user array
foodProducts *currentProduct = [bakeryProductArray objectAtIndex:indexPath.row];
productinfo.productName = currentProduct.productName;
productinfo.productImage = currentProduct.productImgUrl;
productinfo.productDescription = currentProduct.productDescription;
[self.navigationController pushViewController:productinfo animated:YES];
}
There have been others who have over came this using nibs but not storyboard.
Can someone point out where I have gone wrong or something I have fundamentally missed?
(I have another project which fully working with navigation controller only. Though this is the 1st project which I have tried to use with the tab bar navigation).
The best way to handle this with a storyboard is to create a segue to the detail view from your mainViewController. This can be from your actual cell or from the controller. In your prepare for segue method, pass the object to the detail view. This uses a fetchedResultsController but the idea is the same. Get the selected cell and pass the object to the detail view.
Here is a sample of how you could pass it while using a segue from the cell itself. Create a segue from the tableViewCell in IB for "selection". Drag that segue to your detailViewController and set the identifier to ShowDetailView then add the following prepareForSegue method.
Make sure to have a property (foodProduct) on your detailViewController that will hold the reference to your selected object. That's what you will pass from your mainViewController.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowDetailView"])
{
DetailViewController *detailViewController = [segue destinationViewController];
foodProducts *currentProduct = [bakeryProductArray objectAtIndex:[self.tableView indexPathForSelectedRow]];
detailViewController.foodProduct = currentProduct;
}
}
try this .....
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Decriptionview *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"Decription"];//#"Decription" is Storybord Id of UiViewController of Decriptionview
detail.wndecDecription=[SortedDecription1 objectAtIndex:indexPath.row];
detail.wndectitle=[SorttedTitle1 objectAtIndex:indexPath.row];
detail.wndeclink=[SortedLink1 objectAtIndex:indexPath.row];
detail.wndecdate=[SorttedDate1 objectAtIndex:indexPath.row];
detail.imgeurl=[sorttedMainImage1 objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detail animated:YES];
}