Pass data between view controllers WITHOUT segues - ios

I'm using storyboard and I have a view that loads dynamic buttons. On click of this button, I need to load the second view controller and also pass data. I cannot use segue as its dynamic button.
I use following code to load the second view controller
UIStoryboard* sb1 = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone"
bundle:nil];
UIViewController* vc1 = [sb1 instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self.navigationController pushViewController:vc1 animated:YES];
In the 2nd view controller, I need to access about 5 fields from the 1st view controller. How do I pass the data?

You can create a Segue not bounded to a button by ctrl+drag from the first controller to the second one (don't forget to give this segue and identifier).
Next In the IBAction of the button (set via Interface Builder or via addTarget:self action:forControlEvents: ) you can call the [self performSegueWithIdentifier:#"YourSegueIdentifier" sender:button];
You can pass the data to the second controller, as usual, in - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

Try something like that:
Class A
// CLASS_A.h
#import <UIKit/UIKit.h>
#interface CLASS_A : UIViewController {
...
}
- (IBAction)Btn_PushPressed:(id)sender;
...
#end
// CLASS_A.m
#import "CLASS_A.h"
#import "CLASS_B.h"
#implementation CLASS_A
- (IBAction)Btn_PushPressed:(id)sender
{
UIStoryboard* sb1 = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone"
bundle:nil];
CLASS_B* vc1 = [sb1 instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc1.delegate = self;
[self.navigationController pushViewController:vc1 animated:TRUE];
}
....
#end
Class B
// CLASS_B.h
#import <UIKit/UIKit.h>
#class CLASS_A;
#interface CLASS_B : UIViewController {
...
}
#property (weak, nonatomic) CLASS_A *delegate;
....
#end
// CLASS_B.m
#import "CLASS_B.h"
#import "CLASS_A.h"
#implementation CLASS_B
....
#end

This is how to do it in Swift 2.0. Instead of using prepareForSegue,
Swift 3.0
let someViewConroller = self.storyboard?.instantiateViewController(withIdentifier: "SomeViewController") as! SomeViewController
someViewConroller.someObject = self.someObject!
self.navigationController?.pushViewController(someViewConroller, animated: true)
Swift 2.0
let someViewConroller = self.storyboard?.instantiateViewControllerWithIdentifier("SomeViewController") as! SomeViewController
someViewConroller.someObject = self.someObject!
self.navigationController?.pushViewController(someViewConroller, animated: true)

Swift 3
let destinationView = self.storyboard?.instantiateViewController(withIdentifier: "ID") as! ViewController2
destinationView.Value2 = Value1
self.present(destinationView, animated: true, completion: nil)

You can simply use
NSUserDefaults
to store the data and retrieve in what ever page you need
In view controller A
[[NSUserDefaults standardUserDefaults] setObject:aData forKey:#"DATA"];
[[NSUserDefaults standardUserDefaults] synchronize];
In destination Controller
NSData * aData = [[NSUserDefaults standardUserDefaults] valueForKey:#"DATA"];

firstly you can use segue even you have dynamic buttons, just add target method to UIButtons and push view controller using segue in that method. in the second view controller, take few properties and assign values to those properties before you push second view controller. like:
UIStoryboard* sb1 = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone"
bundle:nil];
UIViewController* vc2 = [sb1 instantiateViewControllerWithIdentifier:#"SecondViewController"];
[vc2 setName:#"name"];
[self.navigationController pushViewController:vc2 animated:YES];
before that you need to assign property to a NSString *name in SecondViewController

You can define a protocol: PassValueDelegate,and in the first viewController you can implement this protocol.
UIStoryboard* sb1 = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController* vc1 = [sb1 instantiateViewControllerWithIdentifier:#"SecondViewController"];
//set the delegate for the second view controller,so you can access the values in the first controller
vc1.delegate = self;
[self.navigationController pushViewController:vc1 animated:YES];

Related

Access property of ViewController in Storyboard

NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"drawingboard"];
I want to access vc.property but the property I want to access in not accessible even though the property is in .h file and has a nonatomic, assign property. Is there anyway I can access that? Please help! Thanks in advance.
The vc must be casted to a specific class which is a subclass of UIViewController.
For instance:
Drawingboard *vc = [storyboard instantiateViewControllerWithIdentifier:#"drawingboard"];
If you define the property in the .h file than you don't need to redefine it in the .m. Otherwise you'll be accessing the .m object and not the .h property.
#property (nonatomic) UIViewController *vc;
Above would be your header, below is the implementation
NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
_vc = [storyboard instantiateViewControllerWithIdentifier:#"drawingboard"];
_vc can also be replaced with self.vc depending on preference but that would be how you access it later on. Hope this Helped
Implement prepareForSegue: method as below:-
Lets say CommentsViewController is the class name of your viewController whom you want to push.
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([segue.destinationViewController isKindOfClass:[CommentsViewController class]]) { // Your viewControllerclass
CommentsViewController *controller = [segue destinationViewController];
controller.propertyName = #"Write value here";
}
}

nil delegate in modal view after presentViewController.

My first view in the viewDidLoad has the following code
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Dialpad" bundle:nil];
self.vc = [sb instantiateViewControllerWithIdentifier:#"DialpadBoard"];
self.vc.delegate = self;
The header file contains the definition of the view controller
#property (nonatomic, retain) DialpadTableViewController *vc;
after catching an event the view loads a new modal view
- (void)handleEvent:(UIGestureRecognizer*)recognizer {
[self presentViewController:self.vc animated:YES completion:NULL];
}
The view also contains the method to dismiss the modal view:
- (void) dialpadControllerDidCancel:(SearchDialpadTableViewController *)controller {
[self dismissViewControllerAnimated:YES completion:nil];
}
The last method never gets called.
The problem is that the modal view when it is loaded has nil self.delegate. The new modal view is loaded from the storyboard as seen below. Why the delegate is nil? I cannot how a segue since the view is in another storyboard.
you can try this
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Dialpad" bundle:nil];
UINavigationController *nav= [sb instantiateViewControllerWithIdentifier:#"DialpadBoard"];
((SearchDialpadTableViewController *)[nav viewControllers][0]).delegate = self;
[self presentViewController:nav animated:YES completion:NULL];
Since we have the nav let's take the first controller and assign the delegate
the trick ;)
((SearchDialpadTableViewController *)[nav viewControllers][0]).delegate = self;
Does SearchDialpadTableViewController define a delegate protocol and does it have a property that is specific to that protocol?
The header for that file should look something like:
#protocol ViewControllerDelegateProtocol <NSObject>
- (void)dialpadControllerDidCancel:(SearchDialpadTableViewController *)controller;
#end
#interface ViewController : UIViewController
#property (weak, nonatomic) id<ViewControllerDelegateProtocol> searchPadDelegate;
#end
Then when the user taps Done which is I'm assuming what you're trying to do (send a delegate message when that happens). You would write something like
- (IBAction)donePressed:(id)sender
{
if ([self.searchPadDelegate respondsToSelector:#selector(dialpadControllerDidCancel)]) {
[self.searchPadDelegate dialpadControllerDidCancel:self];
}
}
you must be certain, that self.vc is a class, that you expected. It can be also NavigationController

How to pas data between view controller without using segue in ios?

Helo all,
I am moving from one view controller to another using below code.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"RoloBusinessCard"];
[self.navigationController pushViewController:vc animated:YES];
Now i want to pass some data from one view controller to another like some variable.I have got this code to do this task but i am not making instance of another view controller.I am starting another view controller using storyboard.
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondViewController.str1 = str;
[self.navigationController pushViewController:secondViewController animated:YES];
Please tell me how can i pass data between view controllers in my way?
Solution does not work
decalre NSString in .h file.
#property (nonatomic, strong) NSString *UserId;
Synthesize in .m file
#synthesize UserId;
Code for navigation
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"RoloBusinessCard"];
vc.UserId=#"abc";
[self.navigationController pushViewController:vc animated:YES];
But vc.UserId does not recognized.
You can pass data between two ViewControler with the help of properties.
First in RoloBusinessCard.h ViewControler make a property like this
#property (nonatomic, strong) NSString *str1;
in .m file of this class synthesize it like this
#synthesize str2;
Now like this you can pass value
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"RoloBusinessCard"];
vc.str2=str2
[self.navigationController pushViewController:vc animated:YES];
If you are not able to get str2 in RoloBusinessCard
First Replace UIViewController with Your Viewcontroller Name like this
RoloBusinessCard *vc = [storyboard instantiateViewControllerWithIdentifier:#"RoloBusinessCard"];
or
typecase UIViewController like this
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"RoloBusinessCard"];
(RoloBusinessCard *)vc1=vc
vc1.str2=str2
[self.navigationController pushViewController:vc1 animated:YES];
Hope it help.
Try Like this, Hope it will work.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
SecondViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"RoloBusinessCard"];
vc.str1 = str;
[self.navigationController pushViewController:vc animated:YES];
Here we are just using Navigation stack for passing data to the next controller
create a property in 2nd view controller
#property (nonatomic, strong) NSString *yourString;
in firstView controller action method
object of view controller which you will create on push method do
-(void)btnAtion{
object.yourstring = txtyourfirstvcObject.text
}
In swift, we can do the same
let's suppose we want to pass a Bool Value to the next controller so we can do :
Class ToViewController : UIViewController {
public var isSelected : Bool?
}
Class FromViewController : UIViewController {
#IBAction func onClickFlyingFrom(_ sender: UIButton) {
let tvc = self.storyboard?.instantiateViewController(withIdentifier: "ToViewController") as! ToViewController
tvc.isSelected = true
self.navigationController?.present(vc, animated: true, completion: nil)
}
}

iOS use the delegate pass value not trigger the method

I was test the delegate pass the value in objective-c.
I know there are other methods can pass string between UIViewControllers like NSNotifyCenter..etc.
Now I want to try to use the delegate pass value .
But I encounter some problems.
I use the navigation and there have two UIViewController(FirstUIViewcontroller and SecondUIViewController).
Now I want to use manual to change to SecondUIViewController,not use the button drag to the SecondUIViewController at FirstUIViewController.
So I add the code in the FirstUIViewController.m button action.
- (IBAction)pushBtnAction:(id)sender {
SecondViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self.navigationController pushViewController:controller animated:YES];
}
Then I want to pass the value from the SecondUIViewcontroller when I pop the view controller.
So I add the delegate implement and se the delegate in the FirstUIViewController.m.
- (void)viewDidLoad {
[super viewDidLoad];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
secondVC = (SecondViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
secondVC.delegate = self;
}
-(void) passSecondVC:(SecondViewController *)vc didAddValue:(NSString *)str
{
NSLog(#"second str:%#",str);
}
In the SecondUIViewController.h , I had declare delegate method.
#class SecondViewController;
#protocol SecondViewControllerDelegate <NSObject>
#optional
-(void)passSecondVC:(SecondViewController*)vc didAddValue:(NSString*) str;
#end
#interface SecondViewController : UIViewController
#property (nonatomic,assign) id<SecondViewControllerDelegate> delegate;
- (IBAction)passValueDelegatBtnAction:(id)sender;
In the SecondViewController.m ,
when I click the button will pop self uiviewcontroller and pass the value to FirstUIViewController.
- (IBAction)passValueDelegatBtnAction:(id)sender {
if( [self.delegate respondsToSelector:#selector(passSecondVC:didAddValue:)])
{
[self.delegate passSecondVC:self didAddValue:#"this is string from sencond vc"];
}
[self.navigationController popViewControllerAnimated:YES];
}
(My problems)
But in this status , I always can't get the value in the delegate method in the FirstUIViewController.
I had try to other method like below in the FirstViewController.m
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"segue");
id vc = segue.destinationViewController;
if( [vc isKindOfClass:[SecondViewController class]])
{
SecondViewController *secondVC = vc;
secondVC.delegate = self;
}
}
There are same problem.
I can't get the value from the delegate method.
Have anyone know where the problems?
I post my completely code in here.
Thank you very much.
Alright!
Remove your code from the viewDidLoad: method and set the delegate when you push the secondViewController.
- (IBAction)pushBtnAction:(id)sender {
SecondViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[controller setDelegate:self];
[self.navigationController pushViewController:controller animated:YES];
}
So what was going wrong?
Ans: You create a new object in your viewDidLoad: method and set your firstViewController as delegate to it. Now while pushing you are creating another object of SecondViewController whose delegate is not set.
I downloaded your code & fixed it.
You don't want this line. so comment it,
// UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
// secondVC = (SecondViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
// secondVC.delegate = self;
Edit this method as below,
- (IBAction)pushBtnAction:(id)sender {
SecondViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
controller.delegate = self;
[self.navigationController pushViewController:controller animated:YES];
}
Also edit this method as below,
- (IBAction)passValueDelegatBtnAction:(id)sender {
// if( [self.delegate respondsToSelector:#selector(passSecondVC:didAddValue:)])
// {
[self.delegate passSecondVC:self didAddValue:#"this is string from sencond vc"];
// }
[self.navigationController popViewControllerAnimated:YES];
}
you forgot some code in pushBtnAction..
- (IBAction)pushBtnAction:(id)sender {
SecondViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"]; // It's different to VC you init in viewDidLoad
controller.delegate = self; // you forgot....
[self.navigationController pushViewController:controller animated:YES];
}
prepareForSegue be call when you use segue to navigation.

Passing Data with IBAction

I'need to pass data from a UIviewController to another UIviewController with an IBAction because I want to implement a custom transition effect.
to show the next view I use this code, it work perfectly:
NSString * storyboardName = #"MainStoryboard";
NSString * viewControllerID = #"NextViewController"; // si imposta nello storyboard, subito sotto la classe di appartenenza nell'identity ispector
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
NextViewController * controller = (NextViewController *)[storyboard
instantiateViewControllerWithIdentifier:viewControllerID];
[self passData]
To pass data I tried what I usually do in prepareForSegue, so assign a property to NextViewController.h
#property (assign,nonatomic) int indiceDue;
and use that property to pass data
-(void) passData
{
UIStoryboardSegue* segue = [[UIStoryboardSegue alloc]init];
IbaViewController*dvc = segue.destinationViewController;
dvc.indiceDue = self.indice;
}
The problem is that it don't work. How can I solve my problem?
Call this method inside the ibaction:
NextView*dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"NextView"];;
dvc.indiceDue = self.indice;
[self.navigationController pushViewController:dvc
flipStyle:MPFlipStyleFlipDirectionBit(MPFlipStyleOrientationVertical)];// or the transition that you like

Resources