Unwind segue seems to deallocate my view objects - ios

I'm trying to pass an object using unwind segue. My button unwinds successfully, but all the objects in the view are reinitialized or something. I use prepareForSegue method to prepare my object successfully, but when I access the viewController in my destination segue (through an action button) all the objects are either reinitialized or not allocated.
I'm pretty new at this so any suggestions would be appreciated! Here's the code I'm stupefied with.
//prepareForSegue is called in my view controller i'm trying to unwind from.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ReturnInput"])
{
GLUPipeDataController *dataController;
dataController.length = [[NSNumber alloc] initWithFloat:1.5];
self.dataController = dataController;
[self.dataController print];
}
}
//this done is called in my destination view controller. It is linked in IB by control-draging the unbutton to the exit routine on the connections panel. I then updated the name of the unwind segue in the document outline.
- (IBAction)done:(UIStoryboardSegue *)segue
{
if ([[segue identifier] isEqualToString:#"ReturnInput"])
{
GLUEditViewController *editController = [segue destinationViewController];
if (editController.dataController)
{
self.dataController = editController.dataController;
[self.dataController print];
[[self tableView] reloadData];
}
}
if ([[segue identifier] isEqualToString:#"ReturnInserts"]) {
GLUEditInsertsViewController *editInsertController = [segue destinationViewController];
if (editInsertController.listInserts) {
self.dataController.listInserts = editInsertController.listInserts;
[[self tableView] reloadData];
}
}
}
The call [self.dataController print] in prepareForSegue prints property. But the same call in the done method prints a newly initialized object.

Related

prepareForSegue called before UIButton Action event

Following is my code for button action event.
-(IBAction)reportRepair{
if(![Common hasReportRepairURL]){
NSArray *forms = [[self delegate] getFormsForSection:#"REPORTREPAIR"];
if(forms.count == 0){
[self performSegueWithIdentifier:#"ReportRepairView" sender:self];
}else if(forms.count == 1)
[self getFormByFormID:[[forms objectAtIndex:0] intValue]];
else
[self performSegueWithIdentifier:#"FormsView" sender:self];
}
}
and prepareForSegue is as below:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString: #"RepairDetailView"]){
RepairDetailViewController *dest = (RepairDetailViewController *) [segue destinationViewController];
dest.job = self.selectedJob;
dest.tenancy = self.tenancy;
}else if([[segue identifier] isEqualToString: #"ReportRepairView"]){
ReportRepairViewController *dest = (ReportRepairViewController *) [segue destinationViewController];
dest.tenancy = self.tenancy;
}else if([[segue identifier] isEqualToString: #"FormsView"]){
FormsSearchViewController *dest = (FormsSearchViewController *) [segue destinationViewController];
dest.allowedForms = [[self delegate] getFormsForSection:#"REPORTREPAIR"];
dest.tenancy = self.tenancy;
dest.formSectionType = #"REPORTREPAIR";
}else if([[segue identifier] isEqualToString: #"FormView"]){
FormViewController *dest = (FormViewController *) [segue destinationViewController];
dest.form = self.form;
dest.tenancy = self.tenancy;
dest.formSectionType = #"REPORTREPAIR";
}
else if([[segue identifier] isEqualToString: #"RepairsWebView"]){
WebViewController *dest = (WebViewController *) [segue destinationViewController];
dest.siteURL = [Common getReportRepairURL:self.tenancy];
dest.screenTitle = AGLocalizedString(#"Report a Repair", #"Report a Repair");
}
}
when I debug the code it is know to me, that prepareForSegue method is called before Action event. Due to this, For UI point of view, I am facing some abnormal behaviour in my application.
You should use either Button click or segues from View controller, but not both. So make sure if already have added segues in view controller in storyboard remove it first.
Important Note :
When we add segues directly from storyboard view controllers than prepareForSegue method call immediately when view appears & it will not wait for the button click event.
Hope it helps.
Try to make segues like below images. Don't draw segues from Button to ViewController. If the segues have been added already remove them.

Issue with PFObject

I need to pass a PFObject to 2 views, first one is detail and second is a segue from the detail. I can easily pass the PFObject to the detail, using PFObject *obj = [array objectAtIndex:indexPath.row], detailVC.object = object in prepareForSegue to a property of the detail view controller, but when I try to pass from the detail to the third view, using vc.object = self.object in prepareForSegue then the value of the PFObject in third view is nil. What is the problem?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"segue"]) {
thirdVC *vc = (thirdVC *)segue.destinationViewController;
vc.object = self.object;
}
}
I often found this error when I tried to segue to a VC embedded within its own navigation controller. Make sure it is not, and if it is use this to refer to the controller instead
if ([segue.identifier isEqualToString:#"<#Segue Name#>"]) {
UINavigationController *nav = (UINavigationController *)[segue destinationViewController];
<#UIViewController#> *controller = (<#UIViewController#> *)nav.topViewController;
controller.object = self.object;
}
Other than that, I can only think to log the object inside the second VC's prepareForSegue and see if it exists there

Is a prepareForSegue notify a view controller when a segue is about to preform to another view controller?

Up until now I have used prepareForSegue method to notify a view controller he is about to review a segue from a different view controller, but if i'm the vc that sending the segue, will my prepareForSegue (in he same class of the segue sender) will check if there is a code to preform before he fires the segue?
I'm asking because I got a solution here to preform a simple segue just to go from stable view row which represent notes to the creation page of the note for editing...very simple, but from some reason it's not presenting my note in the creation page, only takes me to a new clean creation page..
So I though maybe it's because the prepareForSegue method..here you can see the question to give you more details How to to create a segue to push back to editing mode from a table view?
Would really appreciate to get your help on this.
This are the 2 methods I added to my NotesList table view controller:
#pragma mark - delegate
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"noteSegue" sender:nil];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"noteSegue"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NMNote *note = [self.notes objectAtIndex:indexPath.row];
NMCreateNotesViewController *destination = [segue destinationViewController];
destination.textField.text = note.content;
}
}
And I made sure the segue identifier in the storyboard is named noteSegue. So why its note working...Im getting a new TextView instead of populating it with the note content :/
This is the error i'm getting:
Thanks!
The prepareForSegue: method is called on the current VC not the destination. UIViewController Class Reference. You can use the method to obtain a reference to the destination VC and set variables/call methods on it before the segue is performed.
Calling the segue like this:
[self performSegueWithIdentifier:#"NAMEOFSEGUE" sender:nil];
You can then prepare the destination VC like this:
#import "NMCreateNotesViewController.h"
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NAMEOFSEGUE"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
[destination createNote]; /* or something similar */
}
}
EDIT:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NMNote *note = [self.notes objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"noteSegue" sender:note];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NAMEOFSEGUE"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
NMnote *note = (NMNote*) sender;
destination.textField.text = note.content;
}
}
To check if there is a code to preform before the segue you can use solution below:
if ([segue.destinationViewController isKindOfClass:[UIViewController class]]) {
UIViewController *nextVC = segue.destinationViewController;
if(nextVC respondsToSelector:#selector(yourMethod)){
[nextVC yourMethod];
}
}
You can check if you are sure to perform the specific segue by implementing this method
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
If you have your note presenting code in viewDidLoad, try moving that to viewDidAppear (in your note editing VC). There used to be an issue when presenting from a TableView row where the segue would fire after VDL was executed.

how to push subtitle from uitableview to detail view controller

i have a project which is basically a uitableview populated with a mutable array and has a search bar
now the uitableview has title and subtitle which are populated with different mutable arrays ..
when you tap on a cell (from the view or from the search view) it pushes the title to a new view controller.
i need the subtitle to be pushed also to the new view controller
i tried every thing i know but i had no success
i have attached the project so you can see how its coded and possibly tell me how to fix it
http://ezzati.net/KuwaitFood.zip
please help
Please replace the function below.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowDetail"]) {
NSString *object = nil;
NSIndexPath *indexPath = nil;
if (self.searchDisplayController.isActive) {
indexPath = [[self.searchDisplayController searchResultsTableView] indexPathForSelectedRow];
object = self.results[indexPath.row];
} else {
indexPath = [self.tableView indexPathForSelectedRow];
object = self.objects[indexPath.row];
}
[[segue destinationViewController] setDetailLabelContents:object];
[[segue destinationViewController] setNumberdetailLabelContents:[sender detailTextLabel].text];
}
}
You have to assign a identifier to the segue (the arrow from your table view controller to the new controller in your storyboard) and then use this function to grab the destination view controller and set it's property with the data you want to send:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"identifier"])
{
SecondViewController *vc = [segue destinationViewController];
// get the selected item index
NSInteger index = [self.tableView indexPathForCell:sender].row;
// set the data property for the second view (pass data)
vc.theProperty = [self.data objectAtIndex:index];
}
Now you can find theProperty on your SecondViewController filled with data from the table view controller.
EDIT: I've reviewed your code. for your case do this:
in -tableView: didSelectRowAtIndexPath: change self to indexPath like this:
[self performSegueWithIdentifier:#"ShowDetail" sender:indexPath];
and in prepareForSegue do this:
DetailViewController *vc = [segue destinationViewController];
// get the selected item index
NSInteger index = ((NSIndexPath *)sender).row;
// index of searched object in self.objects
NSInteger trueIndex = [self.objects indexOfObject:[self.results objectAtIndex:index]];
// set the data property for the second view (pass data)
vc.detailLabelContents = [self.objects objectAtIndex:trueIndex];
vc.numberdetailLabelContents = [self.numbers objectAtIndex:trueIndex];
the problem was because you were using index of self.results and applying it to self.objects which was 0, so you were always getting the first object "You Tube"
change the last line of
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
as below
[[segue destinationViewController] setDetailLabelContents:[sender detailTextLabel].text];

How to use correctly segue with a Tab Bar Controller?

My application use a different master detail, its consist in an initial ViewController with a tableView, but when the user click the Add button in the navigation controller I need send an object using the follow function:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"AddDGV"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
[[segue destinationViewController] setDetailView:object];
}
}
The code works fine when the destination is another ViewController, but my application was designed to have TabBarController instead a ViewController. This TabBar have 2 tabs, each one with a different Navigation Controller, and the first one is the target to the identifier "AddDGV". I created the .m/.h files and associated the class in the storyboard, and set the instance variable "DetailView" as ID.
#property (strong, nonatomic) id detailItem;
The problem is the compiler don't know this variable, because the command [segue destinationViewController] contains the view controller whose contents should be displayed at the end of the segue. As the end of the segue is a TabBarController, the function doesn't work.
Someone knows how fix it???
Typecast the output of
[segue destinationViewController]
as follows
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"AddDGV"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
[(YourDestinationViewController *)[segue destinationViewController] setDetailView:object];
}
}

Resources