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];
Related
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;
}
}
I am trying to use a button to change the image on second viewController , but I don't know how? Do I need to do something or just pass it in prepare for segue like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"the_segue"]){
imageView.image=#"photo.jpg"
}
}
Thanks!
Try this
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"the_segue"]){
secondViewController *VC2 = (secondViewController *)segue.destinationViewController
VC2.imageView.image=#"photo.jpg"
}
}
In your SecondViewController look like
#interface secondViewController : UIViewController
#property(strong,readwrite) UIImageView *imageView;
#end
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.
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:
My segues were added in the storyboard. I want push to a viewController, say Deep_VC, different from the next one in the storyboard, say Next_VC. I'm using:
Deep_VC *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"DeepVC"];
[self.navigationController pushViewController:controller animated:YES];
It goes there, but I get errors. The nav bar tile is for the Next_VC, not the Deep_VC, and the error messages:
Finishing up a navigation transition in an unexpected state . . .
Unbalanced calls to begin/end appearance transitions . . .
My prepareForSegue looks like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"toNextVC"]) {
Next_VC *vc = [segue destinationViewController];
vc.receivedData = [NSMutableArray arrayWithObjects:passData, nil];
}
if ([[segue identifier] isEqualToString:#"toDeepVC"]) {
Deep_VC *vc = [segue destinationViewController];
vc.receivedData = [NSMutableArray arrayWithObjects:passData, nil];
}
}
Can anyone help, please?
I'd rather use performSegue instead of pushViewController in your case. But wait, if you`ve wired your VCs in the storyboard you don't need to push. This will be done automagically by the segue.
EDIT
if (login == successful) {
[self performSegueWithIdentifier:#"toNextVC" sender:self];
} else {
[self performSegueWithIdentifier:#"toDeepVC" sender:self];
}
After that prepareForSegue will be called automatically and there you set your data. pushViewController is not needed as the seque pushes the appropriate VC.
Hope that helps!