I have 2 view controller
Main has a button
Detail has a label: lblDetail
I'm trying to pass data by segue : "sgPushDetail". When click on the button on Main, the label on Detail will be changed.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"sgPushDetail"]) {
DetailViewController *detail = segue.destinationViewController;
detail.lblDetail.text = #"you've already clicked";
}
}
But when i build, the label doesn't change. Please help me with this case!
The DetailViewController is not loaded when you are setting value for the label in prepareForSegue method. Do the following:
Create a property (i.e. NSString) in DetailViewController
Set the value for this property in prepareForSegue method
In viewDidLoad method of your DetailViewController, assign this property value to the label.
Related
I have a view controller (vc1) which has a container view and below that it has a save button . Container view is embed segued to tableview controller(tvc1) having static cells . Each cell has labels and textfields.
I am trying to get the contents of textfields in tvc1 in vc1 .
I tried two methods :
Preparefor segue in vc1:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(#"prepare for segue called in settings view controller.");
NSString * segueName = segue.identifier;
if ([segueName isEqualToString: #"embedseguesettings"]) {
NSLog(#"embed segue called ");
settingsTableViewController *tvc1 = (settingsTableViewController *)segue.destinationViewController;
tvc1.surlTextField.text = #"i got u ";
}
}
i am getting print for "embed segue called ", but the textfield in tvc1 is not updated with my text "i got u". Have i got the tvc1 object properly ?
Instantiate tvc1 in vc1:
- (IBAction)save:(id)sender {
settingsTableViewController *tvc1 = [self.storyboard instantiateViewControllerWithIdentifier:#"settingsTableView"];
NSLog(#"surl textfeild = %#",tvc1.surlTextField.text);
}
But i always get null as output. i type some text to surl textfield an press save . i always get null.
settingsTableViewController is the container view's table view controller and i have only set the no of sections and no of rows in that class. Do i need to dequeue cells , i should not be ? , its a static tableview.
The problem is that you're setting the textField value in tvc1 before the view has loaded.
You should add a property in tvc1…
#property (nonatomic, strong) NSString* someText;
then in your prepareForSegue method, assign to someText and also keep a reference to tvc1
if ([segueName isEqualToString: #"embedseguesettings"]) {
settingsTableViewController *tvc1 = (settingsTableViewController *)segue.destinationViewController;
tvc1.someText = #"i got u ";
self.tvc1 = tvc1
}
and in your tvc1 viewDidLoad
tvc1.surlTextField.text = self.someText
Then in your save method:
- (IBAction)save:(id)sender {
// Don't instantiate a new tvc1
NSLog(#"surl textfeild = %#",self.tvc1.someText);
}
As per - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender flow its still not allocated it outlets so...
The UIViewController isn't loaded at that moment.
You need to set #property values and access that in the viewDidLoad() method
and setup your textFiled text accordingly.
I'm new using storyboards and I'm facing this situation: A uinavigationcontroller contains a view controller (root controller) which contains ten buttons linked each one of then through storyboard to the same view controller.
The behavior of the second view controller depends on the button tapped in the first view controller, but how can identify which button is tapped (like tag value) and pass this info to second view controller?
Thank you.
To add on Daniel's answer:
First, add a public property onto your secondVC that is accessible from your first VC:
#interface SecondViewController : UIViewController
#property (nonatomic) int buttonTagClicked;
#end
You need to set tags up on your UIButtons. This is either done in storyboard or programmatically in your code. I would create a generic IBAction that each button is linked to. You can extract the tag off the button through the sender parameter later.
- (IBAction)buttonClicked:(id)sender
{
[self performSegueWithIdentifier:#"pushSegue" sender:sender];
}
That is linked up to
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"pushSegue"]) {
SecondViewController *destinationVC = (SecondViewController *)[segue destinationViewController];
UIButton *selectedButton = (UIButton *)sender;
destinationVC.buttonTagClicked = selectedButton.tag;
}
}
You can set a segueIdentifier for each connection. Then in your ViewController you could trigger an action based on the identifier you set.
e.g.:
If you select your connection in storyboard you can name it:
And in your ViewController you can trigger an action based on the identifier like this:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"segue1"]) {
UIViewController *destinationVC = [segue destinationViewController];
destinationVC.property = ...;
}
}
I have a view controller namely DetailViewController in which is embedded a container view controller, IndividualDetailsController.
I would like to know whether is it possible that some change in the DetailViewController could bring about changes in the container view controller i.e, the IndividualDetailsController.
For eg, I would want a button click in the DetailViewController to change a text field value in the IndividualDetailsController controller. Is it possible to do so using IBActions? Any help would be much appreciated.
In the method
prepareForSegue
of DetailViewController keep a reference to the embedded one (IndividualDetailsController) in a property of IndividualDetailsController.
Then from an action in DetailViewController you can, for example, change a property of the IndividualDetailsController that can then change its interface accordingly.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MyEmbedSegue"])
{
self.individualDetailsController = (IndividualDetailsController*)[segue destinationViewController];
}
}
then in the action
self.individualDetailsController.textFieldValue = newValue
I'm having some trouble passing data from my UITableView to a UIViewController. I'm using PUSH in storyboard to go from my Cell to the UIViewController, and everything is working well. When I select a cell in my UITableView it pushes to the UIViewController and I get a nice back button to return to the UITableView. My problem is passing data to the UIViewController using the PrepareForSegue method ... this is what I'm doing:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowUserDetailSegue"])
{
UserDetailViewController *userInfo = segue.destinationViewController;
userInfo.myLabel.text = #"Hello World";
NSLog(#"I'm here");
}
}
The label "myLabel" does not change when the UIViewController is displayed. Any idea why?
I've used prepareForSegue before and have been able to pass data, not sure what I'm missing.
Also, xcode is showing all the proper code completions and there are no errors.
Thanks!
At the prepareForSegue stage the destination viewController hasn't yet loaded it's view so userInfo.myLabel is nil.
Add a new property to UserDetailViewController, set that to your string instead and in viewDidLoad set it up in your label.
I have a textField in my ViewController1. I have a push segue to my ViewController2 which also has a textField. I need to set the textField.text in my ViewController2 to be equal to the text in the textField in my ViewController1. Here's the code I have:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqual:#"ViewController2"])
{
ViewController2 *VCT = [segue destinationViewController];
VCT.title = #"View Controller #2";
VCT.textField.text = self.textField.text;
}
}
The title setter works just fine. Why is the textField not working?
You cannot set the text of the UITextField (and any other components like UILabel and UITextView) in the prepare for segue, because all view components of the recently allocated controller are not initialized yet (at this time, they are all nil), they only will be when the viewController is presented (and it's view loaded).
You have to create a NSString property in the presented viewController, and then, somewhere inside your another view controller, like viewDidLoad, set the text of the textField as this property value.
Like this:
In the viewController that will present the another viewController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ViewController2"])
{
ViewController2 *vc2 = [segue destinationViewController];
vc2.myString = self.textField.text;
}
}
And inside the presented viewController:
- (void)viewDidLoad
{
[super viewDidLoad];
(...)
self.textField.text = self.myString;
}
Check and see if "VCT.textField" is not nil at that point. I suspect that you'll find it is nil.
You either need to expose it via "#property (strong) IBOutlet UITextField * textField" or you need to store the string somewhere else (e.g. a "NSString" property?) which then loads the text field when the view is fully loaded.