UITableViewController unrecognized selector sent to instance - iphone

I have a tableviewcontroller and a detailtableviewcontroller when I pass an integer I get
-[UITableViewController setSurveyNumber:]: unrecognized selector sent to instance
Bizard thing is exact same code works for tableviewcontroller to -> uiviewcontroller
table -> table code
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"pushSurveyDetails"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSInteger row = [indexPath row];
SurveyDetailViewController *surveyController = [segue destinationViewController];
surveyController.surveyNumber=row;
}
}
in SurveyDetailViewController.h
#interface SurveyDetailViewController : UITableViewController
{
}
#property int surveyNumber;
#end
SurveyDetailViewController.m
#implementation SurveyDetailViewController
#synthesize surveyNumber;
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Survey Number is %i",surveyNumber);
}
why this error occurs?

The error message indicates that [segue destinationViewController] returns a UITableViewController and not a SurveyDetailViewController as expected.
The controller class can be set in the storyboard file.

Related

[UINavigationController setGoalName:]: unrecognized selector sent to instance 0x7964e2c0

I have created the app with following code. Its working fine with iOS7 but it throws the below error when I run with iOS8.
[UINavigationController setGoalName:]: unrecognized selector sent to instance 0x7964e2c0
My firstViewcontroller.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
GoalDetailsViewController *goalsDetailsViewController = segue.destinationViewController;
NSLog(#"%#",[NSString stringWithFormat:#"%#", [[self.arrCategoryTitle objectAtIndex:indexPath.row] objectAtIndex:indexOfCategory]]);
goalsDetailsViewController.goalName = #"Exercise Daily";
}
My GoalDetailsViewController.h
#interface GoalDetailsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic) NSString *goalName;
Thanks in advance.
Seems like your destinationviewcontroller is a subclass of UINAvigationController.
Try this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
GoalDetailsViewController *goalsDetailsViewController = [(UINavigationController*)segue.destinationViewController topViewController];
NSLog(#"%#",[NSString stringWithFormat:#"%#", [[self.arrCategoryTitle objectAtIndex:indexPath.row] objectAtIndex:indexOfCategory]]);
goalsDetailsViewController.goalName = #"Exercise Daily";
}
The easiest way to handle this crash would be to simply make sure that the destinationViewController is of the type you're expecting before you attempt to set a property on it. Something like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
GoalDetailsViewController *goalsDetailsViewController = segue.destinationViewController;
NSLog(#"%#",[NSString stringWithFormat:#"%#", [[self.arrCategoryTitle objectAtIndex:indexPath.row] objectAtIndex:indexOfCategory]]);
if ([segue.destinationViewController isKindOfClass:[GoalDetailsViewController class]]) {
GoalDetailsViewController *goalsDetailsViewController = segue.destinationViewController;
goalsDetailsViewController.goalName = #"Exercise Daily";
}
}
This change ensures that the destinationViewController is of kind GoalDetailsViewController before treating it as such.

Accessing text from property from another class

I have tableview with the cells and every cell pushes detailViewController. I want to assign text of the cell to a textLabel in detailViewController.
.h class of masterView
#property (strong,nonatomic) NSString *selectedCellText;
.m class of masterView
#synthesize selectedCellText = _selectedCellText;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.selectedCellText = [[[tableView cellForRowAtIndexPath:indexPath] textLabel] text];
NSLog(#"%#",self.selectedCellText);
}
Here NSLog prints name of the cell
.h of detailViewController
#property (nonatomic, copy) listOfTricksViewController *aReference;
.m of detailViewController
#synthesize aReference = _aReference;
- (void)viewDidLoad
{
[super viewDidLoad];
self.detailViewName.text = self.aReference.selectedCellText;
NSLog(#"%#",self.aReference.selectedCellText);
}
Here NSLog prints null.
Modify your method prepareForSegue like this :
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"detailTrick"])
{
DetailViewController *detailViewController = (DetailViewController *)segue.
NSString *object = nil;
NSIndexPath *indexPath = nil;
indexPath = [self.tableView indexPathForSelectedRow];
// Pass data
detailViewController.aString = self.cellObjects[indexPath.row];
}
}
You need to call your DetailViewController and forward the data to this controller (supposing here you have a #property aString in your header of DetailViewController)
.h of detailViewController
#property (nonatomic, strong) NSString *aString;
.m of detailViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.detailViewName.text = self.aString;
NSLog(#"%#",self.aString);
}

Not able to set a Label on a view by using model segue

problem StoryBoard
I want to use the model segue. By clicking on 'Year' button it should go to the 'Year View Controller' click on the table cell and screen is set to initial view controller set the Label 1 in the view controller.
Person.h
#import <Foundation/Foundation.h>
#interface CarObj : NSObject
#property (nonatomic, strong) NSMutableString *Year;
#property (nonatomic, strong) NSMutableString* Name;
#end
After that click on the Name button it should go to the Name View Controller and on click it should save the info of cell to the 'Name' parameter of Person.h.
How to implement this? I am not able to set the Label 1 and Label 2....
for segue I am using :
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"GrabYear"])
{
YearViewController *yvc = [segue destinationViewController];
[yvc setCurrentCar:currentCar];
}
}
and for the row selection I am using:
MenuViewController *mvc = [self.storyboard instantiateViewControllerWithIdentifier:#"MenuSB"];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
CarObj *c = [cars objectAtIndex:[path row]];
[mvc setCurrentCar:c];
[mvc viewDidLoad]; // I am not getting previous view loaded automatically
[self dismissViewControllerAnimated:YES completion:^{}];
the string which I am getting in currentCar.year is not able to set the Label by using
[yearLabel setText:currentCar.year];
The controller's call to [controller view] has not happened in the api's chain of events.
Hence, any value you set on the view's sub controls without first loading child controls, will be overwritten, leaving you befuddled with the mystery.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
id vc = [segue destinationViewController];
MyController *controller = (MyController*)vc;
//You'll need lazy load controller child controls "now"! with this method call
[controller view];
//now you can set controls
controller.myLabel.text = #"Value will now persist";
//note objects not owned by the "view" can be set here without the hack
controller.myContextSting = #"This value will persist without the hack";
}
You problem is this code:
MenuViewController *mvc = [self.storyboard instantiateViewControllerWithIdentifier:#"MenuSB"];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
CarObj *c = [cars objectAtIndex:[path row]];
[mvc setCurrentCar:c];
[mvc viewDidLoad]; // I am not getting previous view loaded automatically
[self dismissViewControllerAnimated:YES completion:^{}];
Because you are creating a new instance of your MenuViewController, configuring it and then throwing it away.
What you want to do is add a delegate property to the year and name view controllers and have your MenuViewController set itself as the delegate in prepareForSegue:. Then, on row selection you would do something like:
[self.delegate setCurrentCar:c];
Instead of what you're currently doing with mvc.

passing value to destination controller

I am passing ID from UITABLEVIEWCONTROLLER to another UITABLEVIEWCONTROLLER but it throw the following error.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITabBarController setCityId:]: unrecognized selector sent to instance 0x75225e0'
here us the prepareForSegue function:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"cityPushToTab"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
featuredViewController *destViewController = segue.destinationViewController;
destViewController.cityId = [productKeys objectAtIndex:indexPath.row];
}
}
the function did well before i call the cityId of featured controller. I have tried to logg the productKeys which print the correct values but it is terminating when I try to assign value to destination view controller object. please help.
Are you sure destViewController is of class featuredViewController ? I'm sure it's not. The crash log tells it's a UITabBarController.
What I recommend is create a class that inherits from UITabBarController. I'll call it MyTabBarViewController. Set the class of your tab bar controller in your storyboard to this new class.
In MyTabBarViewController.h, create a property :
#property (nonatomic, strong) id cityId;
(note that cityId can be of any type you need, e.g. NSString, NSNumber, ...).
Then, change your prepareForSegue code :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"cityPushToTab"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
MyTabBarViewController *destViewController = segue.destinationViewController;
destViewController.cityId = [productKeys objectAtIndex:indexPath.row];
}
}
Next, in the .m files of the 4 view controllers that are in your tab bar, you can use this code to access cityId :
// Cast the viewcontroller's tab bar to your class
MyTabBarViewController *tabBarController = (MyTabBarViewController*)self.tabBarController;
// Access your property
id cityId = tabBarController.cityId;
// You can test to see if it works by casting to an NSString and NSLog it
NSString *cityIdString = (NSString*) tabBarController.cityId;
NSLog (#"%#", cityIdString);

How to pass/send the number of selected row in UITableViewController to another class?

Dudes, i'm having some trouble here in XCODE4.5 and I hope you can help me!
How can I pass or send the integer value of the selected row in UITableViewController to another ViewController, using the method didSelectRowAtIndexPath?
Here is my code :
SecondViewController.h
{
NSInteger myInteger;
}
#property(nonatomic) NSInteger myInteger;
SecondViewControl.m
-(void)viewDidLoad {
NSLog(#" the number is = %d",myInteger); //this is not working, I always get "the number is = 0 "
}
FirstViewController.h
#import "SecondViewController"
//...
FirstViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath) {
NSIndexPath *path = indexPath;
NSInteger theInteger = path.row;
NSLog(#"selected row = %d", theInteger); //code OK
//THE PROBLEM STARTS HERE!!!!!!!!!!!!!!!!!!
SecondViewController *second = [[SecondViewController alloc]init];
[second setMyInteger:theInteger];
// i'm trying to use "second.myInteger = theInteger;" , but it's also not working
}
}
Thank you guys!
Your myInteger iVar is unused b/c of how the compiler generates iVars and synthesizes getters/setters automatically for properties.
The compiler helps you when you declare properties so you don't need to declare your own iVars or use #synthesize unless you want behavior other than the default.
The line #property(nonatomic) NSInteger myInteger; causes the compiler to generate the equivalent of the following in your implementation.
#synthesize myInteger = _myInteger;
Therefore, the iVar being modified by the default setter is _myInteger.
You can do one of the following in SecondViewController. I prefer solution #1 b/c it is cleaner, less code and takes advantage of automatic compiler behavior.
In SecondViewController.h remove the myInteger iVar and in SecondViewController.m change any references to the iVar to either _myInteger or self.myInteger
or
In SecondViewController.m, explicitly synthesize the property to use your iVar by adding #synthesize myInteger;
EDIT: ADDED SPECIFIC EXAMPLE
// SecondViewController.h
#interface SecondViewContoller : UIViewController
#property(nonatomic) NSInteger myInteger;
#end
// SecondViewControl.m
-(void)viewDidLoad {
NSLog(#" the number is = %d", self.myInteger);
}
// FirstViewController.h
#import "SecondViewController"
//...
// FirstViewController.m
//
// rest of implementation
//
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath) {
NSIndexPath *path = indexPath;
NSInteger theInteger = path.row;
NSLog(#"selected row = %d", theInteger);
SecondViewController *second = [[SecondViewController alloc] init];
second.myInteger = theInteger;
// you need to present second somehow, viewDidLoad won't be called until then
// example if using a navigationController
[self.navigationController pushViewController:second animated:YES];
}
}
Passing parameters onto the next one should be done in the prepareForSegue:sender: method assuming you're using Storyboards in Xcode 4.5.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
SecondViewController *second = (SecondViewController *)segue.destinationViewController;
second.selectedIndex = selectedIndex;
}
}
Then in your didSelectRowAtIndexPath: method you can perform the segue:
[self performSegueWithIdentifier:#"YOUR_SEGUE_NAME_HERE"];
And it should pass the parameter to your second view again assuming you have a property in the header file of your SecondViewController like such:
#property (nonatomic, assign) int *selectedIndex;
EDIT:
In context with what you're trying to do you can easily make a private property in your FirstViewController at the top and store your selectedIndex from your didSelectRowAtIndexPath: there and pass it through in the prepareForSegue:
#interface FirstViewController() {
int selectedIndex;
}
And
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedIndex = indexPath.row
}
Hi i think you are missing to synthesize the myInteger Veriable modify your secondviewcontroller.m file
SecondViewControl.m
#synthesize myInteger;
-(void)viewDidLoad {
NSLog(#" the number is = %d",myInteger);
}
Hopefully this will help you :)