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");
}
}
Related
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;
What is wrong with below code. It is crashing with SIGABRT (unrecognized selector sent to instance)
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"%#",valueName);
if([segue.identifier isEqualToString:#"pushView"])
{
secondViewController *svc = (secondViewController *)[segue destinationViewController];
svc.passedName = valueName;
}
}
The valueName iVar is an NSString which i want to pass.
1) Don't forget to embed you FirstViewController with NavigationController
2) Don't forget to set your segue identifier.
3) Use the same code you have:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//for example if you value is "123"
NSString *valueName = #"123";
NSLog(#"%#",valueName);
if([segue.identifier isEqualToString:#"pushView"])
{
secondViewController *svc = (secondViewController *)[segue destinationViewController];
svc.passedName = valueName;
}
}
4) Now, in your secondViewController, log you value in ViewDidLoadto see if it is passed...
- (void)viewDidLoad
{
NSLog(#"value: %#", self.passedName);
}
5) The result you should get:
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 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?
I'm working sample app by storyboard.
When made popoverview, I used the way - 'Embed in navigation controller'.
But I'm getting a big trouble of delegate usage.
It's that don't delegate to popover view's.
[ViweController.m]
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"PopRootViewController"]){
NSLog(#"[segue destinationViewController] :%#", [segue destinationViewController]);
rootViewController = [[RootViewController alloc] init];
rootViewController.delegate = (id)self;
NSLog(#"%#---%#---%#", rootViewController.delegate, self, rootViewController);
}
}
-(void)didTap22 {
NSLog(#"delegate step 1 success!! ");
}
The result of this source like this :
[segue destinationViewController] :<UINavigationController: 0x88660a0>
<ViewController: 0x6b795e0>---<ViewController: 0x6b795e0>---<RootViewController: 0x6b7da60>
but [RootViewController] don't receive the delegation.
[RootViewController.m]
#implementation RootViewController
#synthesize items, delegate;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
....
self.items = mutableFetchResults;
NSLog(#"333333..... %#, ....... %#", self.delegate, self);
}
results :
333333..... (null), ....... <RootViewController: 0x8866520>
RootViewController's delegation is null.
I can't find solution about this.
Anybody help me, please!
I suspect you didn't declare your delegate UIPopoverControllerDelegate in the class declaration of your view controller.
This line is suspicious:
rootViewController.delegate = (id)self;
you don't need to cast self normally if you made the declaration I am mentioning.