Passing value of labels in prepareforsegue - ios

Using the prepareforsegue method, I need to pass the value of each label to the next viewcontroller class. I know I should pass the values in each cell as a single object to the next viewcontroller class, however I am not sure the best way to go about it.

In your next controller, you need to have a variable in the .h file that you can set. Then in prepareForSeque, you can do:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"detailSegue"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
NextViewController *dest = [segue destinationViewController];
NSArray* labels = [[NSArray alloc] initWithObjects: [cell viewWithTag:1], [cell viewWithTag:2], [cell viewWithTag:3], [cell viewWithTag:4], nil];
dest.labels = labels;
}
}
Then in your destination controller's initWithFrame, you can iterate each label and call: text:
for (UILabel* label in self.labels)
{
NSLog(#"%#", [label text]);
}

Don't pass anything. In prepareforSegue, create a reference of source view controller in DestinationVC (Example below)
[(DestinationVC *)segue.destinationViewController sourceVC] = self;
Then in DestinationVC, refer to tableview property of source view controller, run a loop to refer all the cells (example below)
for (NSUInteger i = 0; i < [self.tableView numberOfRowsInSection:0]; i++) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathWithIndex:i]];
//Refer to all subviews and see if they are UIlabel
}

Related

How to pass my id click on CollectionViewCell to other ViewController

I have created gallery view in my app. In that add segment controller , first index is table view and second index is collection view. First index (table view) is proper work in my app, But second index (collection view) show array stored pictures but I want to click on collection view cell and move to another view and pass my UID to another view controller. I tried but could not pass my id. Please help. Thank you
Segue method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Tableview"]) {
NSIndexPath *indexPath = [self.table_view indexPathForSelectedRow];
Detail_view *destViewController = segue.destinationViewController;
destViewController.uid_value = [id_ary objectAtIndex:indexPath.row];
}
else if ([segue.identifier isEqualToString:#"Collectionview"])
{
NSArray *indexPaths = [self.collection_view indexPathsForSelectedItems];
collection *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = [indexPaths objectAtIndex:0];
destViewController.uid_value = [id_ary[indexPath.section] objectAtIndex:indexPath.row];
[self.collection_view deselectItemAtIndexPath:indexPath animated:NO];
}
}
I think you need to improve your code rather then doing split arrays better to user NSObject class manage the array with Object Class for your solution use below code
else if ([segue.identifier isEqualToString:#"Collectionview"])
{
NSArray *indexPaths = [self.collection_view indexPathsForSelectedItems];
collection *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = [indexPaths firstObject]; // you can also use firstObject rather then ObjectAtIndex:0
destViewController.uid_value = [id_ary objectAtIndex:indexPath.row];
[self.collection_view deselectItemAtIndexPath:indexPath animated:NO];
}
try this-
take a global indexPath for ex. NSIndexPath *selectedIndexPath; Now add this line in didSelectItemAtIndexPath i.e.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
selectedIndexPath=indexPath;
[self performSegueWithIdentifier:#"Collectionview" sender:self];
}
now in your prepareForSegue method-
else if ([segue.identifier isEqualToString:#"Collectionview"])
{
collection *destViewController = segue.destinationViewController;
destViewController.uid_value = [id_ary objectAtIndex:selectedIndexPath.row];
// or destViewController.uid_value = [id_ary[selectedIndexPath.section] objectAtIndex:selectedIndexPath.row];
[self.collection_view deselectItemAtIndexPath:selectedIndexPath animated:NO];
}
hope this will solve your issue..:)

Tableview cell with textfields and button

I have a tableviewcell that has two text fields and a button.
The idea is that you fill in the text field, but the button will bring up another viewcontroller that has some sort of calculator.
My problem comes with bringing the value back into the right cell and textfield.
I get at the button click with this in the Configure cell;
[cell setDidTapButtonBlock:^(id sender) {
[self countNotes:cashoutLine.cashCurrency cell:cell];
}];
This calls this extract of code;
-(void)countNotes:(Currency *)cashCurrency cell:(PouchEntryViewCell *)cell
{
NotesCountViewController *notesCountVC = [[NotesCountViewController alloc] init];
notesCountVC.noteCurrency = cashCurrency;
notesCountVC.notesDelegate = self;
notesCountVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:notesCountVC animated:YES completion:nil];
}
All good and the new viewcontroller shows up.
I do the work there and pass back the total using delegate. It arrives happily in the first view controller, but then I'm stuck.
How can I get it to populate the correct cell?
Assuming you're presenting the calculator from the ViewController that acts as the UITableViewDataSource delegate, you can find the correct cell to update the textfield by creating a NSIndexPath property in your NotesCountViewController. Before you present the view controller, set the property. When it is dismissed, pass the NSIndexPath back to your UITableViewDataSource viewController, and find the correct cell with that.
-(void)countNotes:(Currency *)cashCurrency cell:(PouchEntryViewCell *)cell atIndex:(NSIndexPath *)indexPath
{
NotesCountViewController *notesCountVC = [[NotesCountViewController alloc] init];
notesCountVC.noteCurrency = cashCurrency;
notesCountVC.cellIndexPath = indexPath;
notesCountVC.notesDelegate = self;
notesCountVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:notesCountVC animated:YES completion:nil];
}
Then get the cell in the Delegate callback with
PouchEntryViewCell *cell = (PouchEntryViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
cell.textField.text = #"New Text";
In NotesCountViewController
- (id) initWithIndexPath:(NSIndexPath *) indexPath {
self = [super init];
if (self) {
self.indexPath = indexPath;
}
return self;
}
Declare this in your .h and also add an indexPath property.. Then just add the self.indexPath in your delegate call back.
To call it just do:
NotesCountViewController *notesCountViewController = [[NotesCountViewController alloc] initWithIndexPath:[self.tableView indexPathForCell:cell];
Then to retrieve the cell in the del callback:
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

Multiple Segue Storyboard whit TableViewCell using Parse.com

in my app I need to run 2 "Storyboard Follows" in practice, when the user selects the cell is pushed into a specific view controller based on a boolean value.
The Tableview contains a list of exam ... I wish that:
  when the user selects the exam Not Completed is pushed into the ViewController 1
  when the user selects the exam Complete is pushed into the ViewController 2
Until now I always used
- (Void) prepareForSegue: (UIStoryboardSegue *) sender follows: (id) sender
but of course when I connect two follows from the cell, the app crashes
I show you the code
P.S. in the storyboard I connected the cell to two different viewcontroller .. If this is wrong you can tell me how to fix this?
Thanks for everything and sorry if the question is not really a problem :)
I'm used Parse.com
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier]isEqualToString:#"DettaglioOggetto"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *rowObject = [self.objects objectAtIndex:indexPath.row];
if([[rowObject objectForKey:FF_ESAMI_STATUS] boolValue])
{
//DATO CONVALIDATO
PFObject *object = [self.objects objectAtIndex:indexPath.row];
FFDettagliEsami *FFDestinationDetails = [segue destinationViewController];
FFDestinationDetails.FFObjectForDetails = object;
} else if ([[segue identifier] isEqualToString:#"Dettaglio"]){
// NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
FFSchedaEsameConvalidato *FFDestinationDetails = [segue destinationViewController];
FFDestinationDetails.FFObjectForDetails1 = object;
}
} }
Solved ... I connected follows directly from viewcontroller containing the TableView with CTRL + drag the view controller target, then
- (Void) prepareForSegue: (UIStoryboardSegue *) sender follows: (id) sender
{
if ([[segue identifier] isEqualToString: # "SegueDaConvalidare"]) {
NSIndexPath * indexPath = [self.tableView indexPathForSelectedRow];
PFObject * object = [self.objects objectAtIndex: indexPath.row];
FFDettagliEsami * = FFDestinationDetails [more destinationViewController];
FFDestinationDetails.FFObjectForDetails = object;}
    
if ([[segue identifier] isEqualToString: # "SegueConvalidato"]) {
NSIndexPath * indexPath = [self.tableView indexPathForSelectedRow];
PFObject * object = [self.objects objectAtIndex: indexPath.row];
FFSchedaEsameConvalidato * = FFDestinationDetails [more destinationViewController];
FFDestinationDetails.FFObjectForDetails1 = object;}
}
Then I implemented the method didSelectedRowAtIndexPath and now everything is working correctly.

UITableView Accessory Button Segue Not working

I'm having big problems learning how to pass data from the cell accessory button to the detail view controller with segues. If I tap the cell the data is passed to the detail view controller in a NSString *selectedItem; and the label on the other view updates with the word that was in the cell -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"toDetail" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"toDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DrugDetailViewController *destViewController = segue.destinationViewController;
destViewController.selectedItem = [[candyArray objectAtIndex:[indexPath row]] name];
}
}
And i connect a segue on the storyboard from the cell to the detail view with a name "toDeatil" It works when i click the cell it goes to the detail screen, but if i put
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"toDetail" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"toDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DrugDetailViewController *destViewController = segue.destinationViewController;
destViewController.selectedItem = [[candyArray objectAtIndex:[indexPath row]] name];
}
}
Almost exactly the same but from the accessorybutton and I connect a segue on the storyboard from the cell accessorybutton to the detail view with a name "toDetail" when I click the cell it goes to the detail screen, but the information is not there, the label dosent get filled out or just uses the first cell detail all the time.
I've tried heaps of combinations. I've tried making my own accessory button, a UIButton in a custom cell but it just uses the first cells details all the time.
The goal is to get didSelectRowAtIndexPath going to one view and accessoryButtonTappedForRowWithIndexPath going to a different view but I need to tell accessoryButtonTappedForRowWithIndexPath what cell was pressed.
Hope this makes sence.
Thank you
You can pass the indexPath as sender to the performSegueWithIdentifier call, like this:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"toDetail" sender:indexPath];//IndexPath as sender
}
And in your prepareForSegue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"toDetail"]) {
//Detect sender class and act accordingly
NSIndexPath *indexPath = [sender isKindOfClass:[NSIndexPath class]] ? (NSIndexPath*)sender : [self.tableView indexPathForSelectedRow];
DrugDetailViewController *destViewController = segue.destinationViewController;
destViewController.selectedItem = [[candyArray objectAtIndex:[indexPath row]] name];
}
}
You don't need to implement accessoryButtonTappedForRowWithIndexPath.
When prepareForSegue is fired from an accessory view, the sender:(id)sender parameter is set to the UITableViewCell which contains the accessory view. You can then ask the table view for the index of that cell (not the selected index).
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"toDetail"] && [sender isKindOfClass:[UITableViewCell class]]) {
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
DrugDetailViewController *destViewController = segue.destinationViewController;
destViewController.selectedItem = [[candyArray objectAtIndex:[indexPath row]] name];
}
}
That is because [self.tableView indexPathForSelectedRow] will return a NSIndexPath only if the ROW is tapped, not when the accessory button is tapped.
In accessoryButtonTappedForRowWithIndexPath, you will need to pass indexPath.row to the prepareForSegue method manually. Try this:
NSInteger selectedRow;
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
selectedRow = indexPath.row;
[self performSegueWithIdentifier:#"toDetail" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"toDetail"])
{
DrugDetailViewController *destViewController = segue.destinationViewController;
destViewController.selectedItem = [[candyArray objectAtIndex:selectedRow] name];
}
}
What about, if you drive state of what is selected on application delegate! Answer of Raul Juarez do the work, but the target of sender parameter is other!
I have an app that use UITableView, and i need to know what item was touched on accessory button in above screen!
To manage this scenery, i have one property on application delegate, that i update when i touch table view accessory button; so in the next screen, i can retrieve the item touched reading the property of application delegate.
In general, i use de application delegate to code model application (dividing necessary class), so views instances only interact with this model to update necessary states! what i do is focus view work independent of model work!
Maybe some like this:
// Property on Application Delegate
#propety (atomic,readwrite) NSIndexPath* indexTapped;
// Method on UITableViewDelegate instance
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
UIMyAppDelegate* model = (UIMyAppDelegate*)[[UIApplication shared] delegate];
model.indexTapped = indexPath;
[self performSegueWithIdentifier:#"toDetail" sender:self];
}
// Method on another View Controller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIMyAppDelegate* model = (UIMyAppDelegate*)[[UIApplication shared] delegate];
if ([segue.identifier isEqualToString:#"toDetail"]) {
NSIndexPath *indexTapped = model.indexSelected;
DrugDetailViewController *destViewController = segue.destinationViewController;
destViewController.selectedItem = [[candyArray objectAtIndex:[indexPath row]] name];
}
}

Seguing data from one UITableViewController to another UITableViewController via performSelector:withObject:

So what I am trying to do is I have an NSMutableArray of data I need to pass to another UITableViewController. This NSMutableArray is an array of NSDictionaries that contain the information I want to be displayed in the title of each table view cell. Here is my code before I segue.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath* indexPath = [self.tableView indexPathForCell:sender];
if ([segue.identifier isEqualToString:#"Title Query"]) {
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSString* cellText = cell.textLabel.text;
NSMutableArray* photosToBeShown = [self titleQuery:cellText];
if ([segue.destinationViewController respondsToSelector:#selector(setPhotoTitles:)]) {
[segue.destinationViewController performSelector:#selector(setPhotoTitles:) withObject: photosToBeShown];
NSLog(#"%#", photosToBeShown);
}
}
}
The method setPhotoTitles: that is called by the performSelector: withObject: is the setter of the property (NSMutableArray* ) photoTitles on the UITableViewController that I am seguing to because I wanted to collect the array so I could then call the methods below to set the titles of my table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Photo Title Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [self titleForRow:indexPath.row];
return cell;
}
- (NSString *) titleForRow: (NSUInteger) row
{
return self.photoTitles[row];
}
What happens when I run this code is I end up in an infinite loop with calls to my setter method (setPhotoTitles:). Now my question is what is the right conceptual way to get around this problem or how can I implement it this way without ending up in an infinite loop. I have all the information I need in my array but I need to pass the array to the new controller but also be able to use the UITableViewCell method to set the rows titles.
In the prepareForSegue: method, rather than overriding setPhotoTitles:, you should create a NSArray property in the destination view controller, as pass the photoTitles array to the NSArray property of the destination view controller. So your prepareForSegue method would look like this:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath* indexPath = [self.tableView indexPathForCell:sender];
if ([segue.identifier isEqualToString:#"Title Query"]) {
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSString* cellText = cell.textLabel.text;
NSMutableArray* photosToBeShown = [self titleQuery:cellText];
YourCustomViewController *customViewController = segue.destinationViewController;
customViewController.photosArrayProperty = photosToBeShown;
}
}

Resources