I wanna to pass data between controller, but I am getting this error, and I am blocked here :s
Error :
[UITabBarController setUID:]: unrecognized selector sent to instance
Code :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString *test = (NSString *)sender;
if ([segue.identifier isEqualToString:#"segueno"]) {
FirstViewController *VC = (FirstViewController *)[segue destinationViewController];
VC.uID = test;
NSLog(#"%#",VC.uID);
}}
Here is storyboaard
Check what is actual type of VC during runtime. Looks like you cast to wrong type.
To check real type during runtime set breakpoint on line VC.uID = test;. In debug window you should have something like:
VC = (RealClass *) 0x312321312
Real class is not what you expected.
The most possible reason, that VC is UITabBarController. So you have to replace
FirstViewController *VC = (FirstViewController *)[segue destinationViewController];
with
UITabBarController *tabBarController = (UITabBarController *)[segue destinationViewController];
// replace 1 with real index of your FirstVC
FirstViewController *VC = [[tabBarController viewControllers] objectAtIndex:1];
segue destination is UITabBarController. so you need to check viewcontrollers list. then based on that u can look for uID.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString *test = (NSString *)sender;
if ([segue.identifier isEqualToString:#"segueno"]) {
FirstViewController *firstVC ;
UITabBarController *destinat = [segue destinationViewController];
if ([destinat isKindOfClass:[UITabBarController class]]) {
for (id listOfViewControllers in [destinat viewControllers]) {
if ([listOfViewControllers isKindOfClass:[FirstViewController class]]) {
firstVC = listOfViewControllers;
break;
}
}
}
firstVC.uID = test;
NSLog(#"%#",firstVC.uID);
}}
Here is how I pass managedObjectContext between segues
In your class where you will pass the data use prepareForSegue call. (The assumption is this class has a variable called _managedObjectContext which can be passed along to the segue class)
Class to Segue From:
.h file:
#property (weak, nonatomic) NSManagedObjectContext *managedObjectContext;
.m file:
#synthesize managedObjectContext
The call to #synthesize will make the following:
a local variable called _managedObjectContext
a method to getManagedObjectContext
a method to setManagedObjectContext
Additionally add the following method to your class
// Pass on managedObjectContext
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// If the destination VC is able to take the setManagedObjectContext method the current objectContext will be passed along.
if ([segue.destinationViewController respondsToSelector:#selector(setManagedObjectContext:)]) {
[segue.destinationViewController performSelector:#selector(setManagedObjectContext:)
withObject:_managedObjectContext];
} else {
NSLog(#"Segue to controller [%#] that does not support passing managedObjectContext", [segue destinationViewController]);
}
}
Then in my "class" to receive the data I do:
in the .h file i have
#property (weak, nonatomic) NSManagedObjectContext *managedObjectContext;
and in the .m file i have:
#synthesize managedObjectContext;
What this does (with syntehsiation) is make a setManagedObjectContext and getManagedObjectContext call. Upon being about to segue I check to make sure the destinationController will "respond to" this method, if so the data gets set.
clear?
Related
I have this code below that send the row to my another class:
[self performSegueWithIdentifier:#"MeInfos" sender:[NSString stringWithFormat:#"%d",(int)indexPath.row]];
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
MeInfosViewController *viewController = [[MeInfosViewController alloc] init];
viewController.paramethersToLoad = (NSString*)sender;
NSLog(#"Will receive -> %#",sender);
}
In my another class (MeInfoViewController) I have:
.h
#property (nonatomic, retain) NSString *paramethersToLoad;
.m
#synthesize paramethersToLoad;
-(void)viewDidAppear:(BOOL)animated{
NSLog(#"What comes? -> %#",paramethersToLoad);
}
This code has a little problem, in console I receive the following messages:
Will receive -> 4
What comes? -> (null)
Why this is happening and what the best way to solve it?
The view controller you're creating in prepareForSegue: isn't the instance that the segue will actually load. The view controller that actually gets displayed is created by the iOS runtime, and is passed to you as a property in the segue.
What you want is:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
MeInfosViewController *viewController = (MeInfosViewController *)segue.destinationViewController;
viewController.paramethersToLoad = (NSString *)sender;
}
Your prepareForSegue should look like this :
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"MeInfos"]) {
// Get reference to the destination view controller
MeInfosViewController *viewController = [segue destinationViewController];
viewController.paramethersToLoad = (NSString*)sender;
}
}
Ok this really makes me headache. I have ViewController (using replace) that I assign its delegate property
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"spoSelectionDemoPlanSegue"])
{
SPOSelectionViewController * vc = [segue destinationViewController];
vc.delegate = self;
NSLog(#"spo segue %#", vc.delegate); //returns current ViewController
}
}
SPOSelectionViewController.h
#property (nonatomic, assign) id<SPOInputDelegate> delegate;
SPOSelectionViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"delegate didload spo %#", delegate); //returns (null)
}
Somehow it prints null! However there is my other ViewController (using popover) that I try to assign its delegate and it does not null. Anyone can give me suggestion?
As I expected and this is silly, since the storyboard's segue is to a navigationController, so actually the destinationViewController is the navigationController not SPOSelectionViewController.
So I solved it by this way:
UINavigationController* navController = segue.destinationViewController;
SPOSelectionViewController * vc = (SPOSelectionViewController*)navController.topViewController;
vc.delegate = self;
I'm making an iOS app but I'm trying to send an object to another view controller but it throws me this error
Blockquote-[UINavigationController setUserObject:]: unrecognized selector sent to instance 0x156aa330
Here's my code:
loginViewController.m
this is user it's already allocated the object with the values of name, email, and lastname
#import "PerfilViewController.h"
#import "User.h"
#interface LogInViewController (){
User *user;
}
#end
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"loggedIn"]) {
user.name = self.nameText.text
user.lastname = self.lastNameText.text
PerfilViewController *pvc = [segue destinationViewController];
[pvc setUserObject: user];
}
}
In my destination controller I have this its as well allocated on viewDidLoad
#import "PerfilViewController.h"
#import "User.h"
#interface PerfilViewController (){
User *user;
}
#end
#implementation PerfilViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setViewValues];
[self.navigationItem setHidesBackButton:YES];
user = [[User alloc] init];
}
#pragma mark - Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
-(void)setUserObject:(User *)userToSet{
user = userToSet;
}
The problem is that the destinationViewController is a UINavigationViewController so PerfilViewController should be its rootViewController
if([[segue identifier] isEqualToString:#"loggedIn"]) {
UINavigationController *navigationController = [segue destinationViewController];
PerfilViewController *pvc = navigationController.rootViewController;
[pvc setUserObject: user];
}
My guess by looking at the code provided is that [segue destinationViewController] is not of the class PerfilViewController.
you could try checking to see if pvc has a method names setUserObject and then call that method if pvc responds to it. If not, then log out what class pvc actually is to help you debug. This should handle that:
if ([pvc respondsToSelector:#selector(setUserObject)]) {
[pvc setUserObject: user];
} else {
NSLog(#"pvc is of class \"%#\"", [s class]);
}
I'm trying to learn more about Objective C blocks and how they work. I've set up a simple project with two UIViewControllers embedded in a UINavigationController in Storyboard. I'm attempting to change the background color of the first ViewController's view from the second view controller. Here's some code:
ViewController.m
#implementation ViewController{
ColorBlock _colorBlock;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"theSegue"]){
SecondViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.colorBlock = _colorBlock;
}
}
- (IBAction)moveToSecondViewController:(id)sender {
__weak id weakSelf = self;
_colorBlock = ^{
[[weakSelf view] setBackgroundColor:[UIColor redColor]];
};
}
SecondViewController.h
typedef void (^ColorBlock)(void);
#interface SecondViewController : UIViewController
#property (readwrite, copy) ColorBlock colorBlock;
#end
SecondViewController.m
- (IBAction)buttonTapped:(id)sender {
if(self.colorBlock){
self.colorBlock();
}
}
The first ViewController's background color isn't being changed because in the buttonTapped: method of SecondViewController.m, self.colorBlock is nil, causing the block invocation not to be called. I thought I had successfully set the block in prepareForSegue:sender:. Why is my block property nil?
In your prepareForSegue, the destination has already been instantiated. So assuming that SecondViewController is the destination, you can do:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"theSegue"]){
SecondViewController *vc = segue.destinationViewController;
NSAssert([vc isKindOfClass:[SecondViewController class]], #"destination is not SecondViewController class");
vc.colorBlock = _colorBlock;
}
}
I have a ViewController that has a couple of buttons on it created in Interface Builder. The first button will display a popover linked up in IB, it is linked to a UINavigationController and has a TableView under it with a class of PopupViewController.
The second button, I have an action setup for goToCategory and when clicking on that, I want to set a property on the PopupViewController
ViewController.m
//go to category
-(IBAction)goToCategory:(id)sender{
NSLog(#"GO TO CAT");
//PopupViewController *popupVC = [self.storyboard instantiateViewControllerWithIdentifier:#"popoverVC"];
//popupVC.currentLevel = 1;
[self performSegueWithIdentifier:#"popoverSegue" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSLog(#"seg1");
if ([[segue identifier] isEqualToString:#"popoverSegue"]){
//PopupViewController *popupVC = (PopupViewController *)[[segue destinationViewController] visibleViewController];
//PopupViewController *popupVC = [segue destinationViewController];
PopupViewController *popupVC=[[[segue destinationViewController]viewControllers]objectAtIndex:0];
popupVC.test = #"just a test";
NSLog(#"seg2");
}
}
PopupViewController.h
#property (nonatomic, strong) NSString *test;
PopupViewController.m
#synthesize test;
-(void)viewDidLoad{
NSLog(#"test: %#", test); //returns test: (null)
}
I've found a lot of answers on SO, hence some of the commented out lines in my prepareForSegue. But none of these set the value of test. PopupViewController *popupVC = [segue destinationViewController]; throws an error due to it referring to the UINavigationController so I can't use that as it is, even though that seems to be the way to do it in a lot of answers I've seen. But no matter which way I try doing it, the output is always null?
UPDATE:
PopupViewController *popupVC = (PopupViewController *)[[segue destinationViewController] visibleViewController]; and PopupViewController *popupVC=[[[segue destinationViewController]viewControllers]objectAtIndex:0]; from my prepareForSegue above both work on the 6.1 simulator. My iPad's iOS is 5.1.1 which it isn't working on. Is there something different I need to do for iOS 5?
Try this
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"seg1");
if ([[segue identifier] isEqualToString:#"popoverSegue"])
{
UINavigationController *navController = (UINavigationController*)[segue destinationViewController];
PopupViewController *popupVC = [navController topViewController];
popupVC.test = #"just a test";
NSLog(#"seg2");
}
}