Pass NSMutableDictionary from one view to another [duplicate] - ios

This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 6 years ago.
I am trying to pass data from one ViewController to another ViewController.
Firstviewcontroller.m
-(void)NavigateToAnotherScreen:(NSMutableDictionary*)dict{
[self performSegueWithIdentifier:#"NavDashBoardToInfo" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NavDashBoardToInfo"])
{
InfoViewController *vc = [segue destinationViewController];
[vc setAppointmentDictionary:dict];
}
}
Secondviewcontroller.h
#property (strong, nonatomic) NSMutableDictionary *AppointmentDictionary;
Secondviewcontroller.m
#synthesize AppointmentDictionary;
- (void)viewWillAppear:(BOOL)animated{
NSLog(#"dict===>%#",AppointmentDictionary); // This gives me null
}
Please help me. What i am doing wrong.
I am getting AppointmentDictionary = (null) in viewwillappear.
Though I am doing proper copy of this.

try this
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector:#selector(setAppointmentDictionary:)]) {
[segue.destinationViewController performSelector:#selector(setAppointmentDictionary:)
withObject:dict];
}
}

Try this one:
-(void)NavigateToAnotherScreen:(NSMutableDictionary*)dict
{
[self performSegueWithIdentifier:#"NavDashBoardToInfo" sender:dict];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
InfoViewController *info = segue.destinationViewController;
info.AppointmentDictionary = sender;
}

If you are using performsegue for navigation then you can use below method for transferring data between ViewControllers
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NavDashBoardToInfo"])
{
InfoViewController *info = [segue destinationViewController];
info.AppointmentDictionary = "Value you want to pass";
}
}

You are creating InfoViewController instance and not pushing that view controller. You doing a "performSegueWithIdentifier" here new instance will create, so you first instance "info" is not passing here. You can do in other way.
InfoViewController *info = [[InfoViewController alloc] init];
info.AppointmentDictionary = [dict mutableCopy];
[self.navigationController pushViewController: info animated:true];
Option 2:
-(void)NavigateToAnotherScreen:(NSMutableDictionary*)dict{
[self performSegueWithIdentifier:#"NavDashBoardToInfo" sender: [dict mutableCopy]];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"NavDashBoardToInfo"]) {
InfoViewController *viewController = (InfoViewController *)segue.destinationViewController;
viewController.AppointmentDictionary = (NSMutableDictionary *)sender;
}
}
In the prepareforsegue method you have to pass the value like mentioned above.
Note: make sure your destination view controller is InfoViewController

If you are using performSegueWithIdentifier then provide the body in function . Don't create any new instance using code and provide segue in storyboard -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"YourController_Segue"]) {
YourController *viewController = (YourController *)segue.destinationViewController;
viewController.AppointmentDictionary = (NSMutableDictionary *)sender;
}
}

Related

id to NSString return null when passing to another class

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;
}
}

Send value from MainViewController to ContainerViewController?

I'm developing an app, I want to send value from MainViewController to ContainerViewController. I've added delegate from MainVC to Container(A) and i defined one method to send values. But this method is not working. I think my usage of prepareForSegue is wrong. Is delegate usable for two way communication between two Views with different methods ?
I've added image to describe my situation.
Thanks for helpings.
Here is my MainVC code block;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"layersViewSegue"]) {
[ (LayersViewController *)segue.destinationViewController setDelegate:self];
}
else if ([segue.identifier isEqualToString:#"addLayerSegue"]) {
[ (AddLayerViewController *)segue.destinationViewController setDelegate:self];
}
}
Container A code block
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"layersViewSegue"]) {
[ (ViewController *)segue.destinationViewController setDelegate:self];
}
}
Something like this:
YourDestinationController.h // container
#property (strong, nonatomic) NSString *assignableString // any object/variable
MainViewController.m
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"yourSegueIdentifier"])
{
YourDestinationController *yourDestinationController = (YourDestinationController*)segue.destinationViewController;
yourDestinationController.assignableString = /* your string */;
}
}

How do i get segue.destinationViewController isKindOfClass: x, to recognize the destination class?

I'm trying to get a simple NSLog message if the destinationviewcontroller isKindOfClass like this:
FirstViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.destinationViewController isKindOfClass:[SecondViewController class]]) {
NSLog(#"The destinationViewController isKindOfClass SecondViewController");
}
Within the storyboard i have ctrl+dragged from a bar button item in the FirstViewController to the SecondViewController and chosen modal segue.
I've also made sure to #import the SecondViewController.h in FirstViewContrller.m and i have given the SecondViewController the "custom class" of SecondViewController in the identity inspector.
Do i need to add/do something else, because I'm not getting the NSLog message at this point.
Edit: I forgot to inform that i did in fact embed the secondViewController in a navigationViewController.
This should work for you:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UINavigationController *navigationController = segue.destionationViewController;
if ([navigationController.viewControllers[0] isKindOfClass:[SecondViewController class]]) {
NSLog(#"The destinationViewController isKindOfClass SecondViewController");
}
But if you want something more generic I would do:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
id dvc = segue.destinationViewController;
if ([dvc isKindOfClass:[UINavigationController class]] && ((UINavigationController *)dvc).viewControllers > 0) {
dvc = [[dvc viewControllers] firstObject];
}
NSLog(#"The destinationViewController is: %#", NSStringFromClass([dvc class]));
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
HomeViewController *edit=[segue destinationViewController];
if ([HomeViewController.viewControllers[0] isKindOfClass:[CheckViewController class]])
{
//You are ready for coding here
}
}
Try this code. This might help.
First you would have to set destinationViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"YourSegueIdentifierHere"] )
{
//Now you can assign here the destinationViewController
SecondViewController *secondController = [segue destinationViewController];
//now you don't need this but if you want you can
if([segue.destinationViewController isKindOfClass:[SecondViewController class]])
{
NSLog(#"The destinationViewController isKindOfClass SecondViewController");
}
}
}
You can use [segue.destinationViewController isKindOfClass:[SecondViewController class]]
inside the if statement if you want.But its not needed now you can get the Identifier from your xcode.

Passing data from one ViewController to other in seque

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:

Deactivate push-animation in segue

I've one problem. I have a ViewController1 whcich opens the ViewController2 through a push-segue. //Both are NavigationControllers
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"show2"])
{
ViewController2 *vc2 = [segue destinationViewController];
}
}
But is it possible to deactivate the animation of this push-action, so it directly shows the new ViewController?
Why not just do something like this?
[ViewController1 pushViewController:ViewController2 animated:NO];

Resources