so I am trying to pass data from my cell (populated with queryForTable method) through a segue to another viewController. I am using the prepareForSegue method and my code looks like:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"profile"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
//UINavigationController *nav = [segue destinationViewController];
ProfileViewController *userProfile = [segue destinationViewController]; //(ProfileViewController *) nav.topViewController;
userProfile.userInfo = object;
}
}
in my VC I have the property defined:
#property (weak, nonatomic) PFObject *userInfo;
but when I run my code I get the error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController setUserInfo:]:
It looks like the viewController you're pulling out of the segue isn't a ProfileViewController - the error you're getting states:
-[UIViewController setUserInfo:]:
Note UIViewController, not ProfileViewController. This would seem to indicate that your segue's destination viewController isn't exactly what you think it is.
Check your destination viewController's class in your Storyboard. Is it set to ProfileViewController? Is your ProfileViewController embedded inside another viewController (like a navigationController - looking at your commented out code, you seem to have treated it as such before)? If so, you might need to do a big more digging to get a reference to the correct viewController.
Related
On my app I decided to change my segue to a Show Details segue in the story board as I wanted the affect of the storyboard coming from the bottom of the screen, and thus I needed some way to bring the user back, so I inserted a navigation into the destination view. However now I get:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController setImageData:]: unrecognized selector sent to instance 0x7fbdfa887600'
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"infoSegue"])
{
// Get reference to the destination view controller
DetailsViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
int num = (int)[self getIndexNum];
NSString *dictionaryKey = _results[num];
Image *image = _dataDictionary[dictionaryKey];
vc.imageData = image;
NSLog(#"Vendor ID %#",image.vendorId);
}
}
Has the navigation become the parent of the view or something?
As destinationViewController returns the generic type UIViewController you have to do a type cast.
DetailsViewController *vc = (DetailsViewController *)[segue destinationViewController];
if your destination view controller is a navigation controller, then you shouldn't set the image on navigation controller!! Also as #vadian from the answer said, you need to cast the return type of uiviewcontroller!!!
UINavigationController *navController = [segue destinationViewController];
DetailsViewController *viewController = (DetailsViewController *)([navController viewControllers][0]);
[viewController setimageData:image];
Make sure imageData is of kind UIImage. If it is of type NSData, you might need to do:
[viewController setimageData:[UIImage imageWithData:imageData]];
I'm using Objective-C. I set a segue from a table view cell to a new view controller, and I want to set the properties for the new view controller using this method:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString: #"detail"]){
if([segue.destinationViewController isKindOfClass:[detailViewController class]]){
detailViewController *detail = (detailViewController *)segue.destinationViewController;
detail.label.text = #"QQQQQ";
}
}
I've set the segue's identifier to #"detail" already, and also connected the label code with the view controller in storyboard. But when I run this in my simulator, the label would never change.
at the time when prepareForSegue is called the destinationviewcontroller's outlets are not set yet.
what you have to do is create a property in your detailViewController class like
#property (copy, nonatomic) NSString *detailText;
then in prepareForSegue:
detailViewController *detail = (detailViewController *)segue.destinationViewController;
detail.detailText = #"QQQQQ";
and in your detailViewControllers viewDidLoad:
self.label.text = self.detailText;
A few hours ago this code gave me no problems, however, after updating my XCode
my XCode and removing a 3rd party framework, it is suddenly giving me the above exception. I'm extremely confused because I don't think anything's changed between then and now that could cause the problem besides updating my XCode. Can anyone see an issue?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
/*We check to make sure the segue corresponds to segue we created when a cell is selected*/
if ([[segue identifier] isEqualToString:#"show"]) {
/*Get a pointer to the selected row*/
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
/*Get a pointer to the ViewController we will segue to*/
ViewController *viewController = segue.destinationViewController;
/*Pass the dialect and code back to the ViewController*/
viewController.language = self.languages.allKeys[indexPath.row];
viewController.code = [self.languages objectForKey:viewController.language];
}
}
Specifically, the following two lines are causing the exception:
viewController.language = self.languages.allKeys[indexPath.row];
viewController.code = [self.languages objectForKey:viewController.language];
Your segue's destination controller is a UINavigationController, your view controller is likely the top view controller of that navigation controller. You probably want:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
/*We check to make sure the segue corresponds to segue we created when a cell is selected*/
if ([[segue identifier] isEqualToString:#"show"]) {
/*Get a pointer to the selected row*/
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *navController = segue.destinationViewController
/*Get a pointer to the ViewController we will segue to*/
ViewController *viewController = navController.topViewController;
/*Pass the dialect and code back to the ViewController*/
viewController.language = self.languages.allKeys[indexPath.row];
viewController.code = [self.languages objectForKey:viewController.language];
}
}
My storyboard controllers: http://i.stack.imgur.com/4LBEd.png
MenuViewController -> ChooseViewControler -> MapViewController and EditViewController.
I need to pass variable called address from MapViewController or EditViewController to MenuViewController. How i can implement this?
I try to use delegate, from this answer Passing Data between View Controllers
but dont understand, how to tell MapViewController or EditViewController that MenuController is its delegate before we push its on nav stack.
I do this at EditVC and its worked:
- (IBAction)OkButton:(id)sender {
NSString *address = addressInput.text;
MenuTableViewController *menuVC =
[self.navigationController.viewControllers objectAtIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
UITableViewCell *cell = [prevVC.tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = address;
[self.navigationController popToViewController:menuVC animated:YES];
}
I guess you have the classes of these viewcontrollers as
MenuViewController.h,
MenuViewController.m
ChooseViewControler.h,
ChooseViewControler.m
MapViewController.h,
MapViewController.m
EditViewController.h,
EditViewController.m
There is this method called -PrepareForSegue called when you perform a segue either programatically(performSegue method) or by using push or model in navigation controller
implement this on your source ViewController (VC) ie, if you are passing from MapViewController to EditViewController ,
Implement this in the .m file of MapViewController.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"toEditViewController"])
{
EditViewController *destinationVC=(EditViewController*)segue.destinationViewController;
destinationVC.address=self.address;
}
}
Note that you have to identify the segue which is called by its name give in the storyboard
There many be many more segues you need to prepare...you need to do all this in the same method.
identify the segue by name>prepare the methods
UITableView in my app is managed using NSFetchedResultsController and I want to implement Master-Detail behaviour but everytime I tap on a cell I get this -[UIViewController setActivity:]: unrecognized selector sent to instance 0x176a7660 error...
I don't know what is going on because my code is based on Apple's Master-Detail demo app.
Here is prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"activitySegue"]) {
ActivityDetailsViewController *advc = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Activity *activity = (Activity *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
[advc setActivity:activity];
}
}
And of course, there is declared #property in destinationViewController. I think that there could be something with this NSManagedObject and it is not passed properly to destination... But this is only my guess.
It looks like the name of the view controller class in your storyboard for the detail view controller is not set, so an instance of UIViewController is created instead of an instance of ActivityDetailsViewController.
Set the name of the view controller in the story board to ActivityDetailsViewController.
I think issue in this line
Activity *activity = (Activity *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; Is this returning activity object ?