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
Related
im still having problems with my segue
i have at the moment
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Check that a new transition has been requested to the DetailViewController and prepares for it
if ([segue.identifier isEqualToString:#"WeddingDetail"]){
// Capture the object (e.g. exam) the user has selected from the list
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
// Set destination view controller to DetailViewController to avoid the NavigationViewController in the middle (if you have it embedded into a navigation controller, if not ignore that part)
UINavigationController *nav = [segue destinationViewController];
DMKWeddingDetailViewController *detailViewController = (DMKWeddingDetailViewController *) nav.nextResponder;
detailViewController.exam = object;
NSLog(#"object details: %#",object);
}
}
i was hoping that exam would hold the data but it isnt the data is held in object. but not sure how to pass object over to detail view controller.
in my detailview controller i have a list if textlabels
self.name.text = [self.exam objectForKey:#"name"];
but they are not populating
in case that the destination ViewController is a UINavigationController, I think the problem is in
DMKWeddingDetailViewController *detailViewController = (DMKWeddingDetailViewController *) nav.nextResponder;
you should use this instead
DMKWeddingDetailViewController *detailViewController = (DMKWeddingDetailViewController *) [nav topViewController];
and if the destination is your target ViewController you should use
DMKWeddingDetailViewController *detailViewController = (DMKWeddingDetailViewController *) [segue destinationViewController];
I'm trying to pass data(_claimReportToDetailView) from viewDidLoad (of MasterVC) to DetailVC. It's always null.
#interface LAMasterViewController ()
{
NSArray *_claimReports;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_claimReports = [[LADataModelController getSingleton] getClaimReportsOrderedByAccessedDate];
LADetailViewController *detailViewController = [[LADetailViewController alloc] init];
detailViewController.claimReportToDetailView = (LAClaimReport *)_claimReports[0];
NSLog(#"claim%#",detailViewController.claimReportToDetailView); // captures here properly.
}
#interface LADetailViewController : UIViewController
#property(nonatomic ) LAClaimReport *claimReportToDetailView;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"sdfdf%#", _claimReportToDetailView); // logs null always.
}
Your viewDidLoad seems strange. You have this line:
LADetailViewController *detailViewController = [[LADetailViewController alloc]init];
Yet you say that the view controller is on the storyboard.
I think what is happening is that you are creating this VC, and setting it's property, but the Storyboard is loading a completely new VC, for which you haven't set the property.
Usually, the way you pass information to VCs on Storyboards is in the prepareForSegue: method.
You have to pass the data to the details view controller in prepareForSeque method in master view controller:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) { //<-make shire the segue identifier match one in storyboard
_claimReports = [[LADataModelController getSingleton] getClaimReportsOrderedByAccessedDate] ;
LADetailViewController *vc = (LADetailViewController*)[sender destinationViewController];
vc.claimReportToDetailView = (LAClaimReport *)_claimReports[0];
}
}
This should fix your project. Give it a try
//Allocating LADetailViewController instance
LADetailViewController *detailViewController = [[LADetailViewController alloc]init];
//Connecting it the specified VC on storyboard
detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"yourVCID"];
//Now the connection is set, so pass the data you need
detailViewController.claimReportToDetailView = (LAClaimReport *)_claimReports[0];
//Depending on present or push you should try one of the 2 lines
[self.navigationController pushViewController:detailViewController animated:YES];
//or
[self presentViewController:detailViewController animated:YES completion:nil];
This happens because whenever you navigate from one UIViewController to other, it is initialized again, so rather than setting value in viewDidLoad, try to set value on the event when you perform navigation and make navigation through code rather than with segue.
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.
Basically, i'm using the prepareForSegue method to transition to another view within my storyboard, my view had to be embedded in a navigation controller in order to display the navigation bar so I am passing variables in such a way:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"exploreAddSelected"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
AddTableViewController *controller = (AddTableViewController *)navController.topViewController;
controller.tagName = tagName;
}
}
My issue is I need to be able to set some method values in the actual view controller when using the prepareForSegue method, as you can do when using pushViewController as below:
DetailViewController *detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
detailViewController.tagName = tagName;
[detailViewController setCurrentHashtag:nil];
[navigationController pushViewController:self.detailViewController animated:YES];
I need to be able to set the "setCurrentHashtag" method, that is declared in the view controller that the segue "exploreAddSelected" goes to. How would I do this?
The answer to this is actually extremely obvious, but it takes me to ask the question to realise the answer myself.
You can simply set:
controller.currentHashtag = nil;
Where currentHashtag is a newly declared instance in the view controller.
Then in the actual view controller set:
[self setCurrentHashtag:currentHashtag];
Just add the currentHashtag to the method.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"exploreAddSelected"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
AddTableViewController *controller = (AddTableViewController *)navController.topViewController;
controller.tagName = tagName;
[controller setCurrentHashTag:nil]; //add this line
}
}
I'm not sure what you are doing here. If the segue points to a view controller directly (and nor via another navigation controller), you do not need the mapping to topviewcontroller, but use the destinationcontroller directly.
I am having trouble with a Navigation Controller in my iOS project which uses Storyboards.
The main part of the project is a UITabBar. When the app loads for the very first time the screen RegisterViewController is presented:
When the user taps on the "Register" button a HTTP POST request is made, then upon receiving the response (JSON object) the screen QuestionnaireViewController is presented using:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
QuestionnaireViewController *questionnaireViewController = [mainStoryboard instantiateViewControllerWithIdentifier:#"QuestionnaireView"];
[questionnaireViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[questionnaireViewController setQuestionsAndAnswers:_questionsAndAnswers];
[self presentViewController:questionnaireViewController animated:NO completion:nil];
When the user taps on a cell in QuestionnaireViewController a message is sent to prepareForSegue:sender:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UINavigationController *navigationController = segue.destinationViewController;
AnswersViewController *answersViewController = [[navigationController viewControllers] objectAtIndex:0];
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
NSArray *answers = [[_questionsAndAnswers objectAtIndex:indexPath.row] objectForKey:#"answers"];
[answersViewController setAnswers:answers];
}
At this point the app crashes with an error of:
-[AnswersViewController viewControllers]: unrecognized selector sent to instance.
Below is a more comprehensive overview of my storyboard, which may help in understanding where I have gone wrong:
I am stumped as to how to fix this, and am hoping that someone out there is able to help.
Thanks,
Nick
First, you should present the navigation controller, not its root view controller. Then when you want to populate the root view controller with some data, you need to reference it as the navigation controller's root view controller:
UINavigationcontroller *questionnaireNavController = [self.storyboard instantiateViewControllerWithIdentifier:#"QuestionnaireNavigationController"];
[questionnaireNavController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
QuestionnaireViewController *qvc = (QuestionnaireViewController *)[questionnaireNavController topViewController];
[qvc setQuestionsAndAnswers:_questionsAndAnswers];
[self presentViewController:questionnaireNavController animated:NO completion:nil];
Second, in prepareForSegue:sender: you don't need to reference a navigation controller at all:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
AnswersViewController *answersVC = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
NSArray *answers = [[_questionsAndAnswers objectAtIndex:indexPath.row] objectForKey:#"answers"];
[answersVC setAnswers:answers];
}
You are not getting the navigationController properly. Instead of segue.destinationViewController, use self.navigationController
By calling segue.destinationViewController, you are getting a pointer to the VC you are segueing to (AnswersViewController) which doesn't understand the message viewControllers because it is not a UINavigationController.
Also the AnswersViewController is objectAtIndex:1 I believe, check this though.