Is it possible to have one view controller save data or control two views?
Say like a 2 page questionnaire. Instead of have a view controller for each page can one view controller save data from both?
You can, yes, but only one view can be considered the view controller's actual view (the property)
This is important because sublassed view controller methods like
-(void)viewDidLoad
-(void)viewWillAppear
etc
will only call for the actual view of the view controller.
Simple answer YES you can have one view controller and control multiple views on that view controller.
I realized that I have to still treat the second page differently even though it uses the same view controller.
I solved my problem by
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
Test *vc = [segue destinationViewController];
vc.testInt = 2;
}
Related
I have created a signup form in the parent controller and integrated a navigation view controller. Then I connected both the controllers through push segue.
I am stuck with how to transfer data from UITextField in the parent view controller to the navigation controller using the click event of the button placed on the signup form.
Anybody please help me.
Thanks
When a segue is triggered, before the visual transition occurs, the storyboard runtime invokes prepareForSegue:sender: method of the current view controller.
By implementing this method, you can pass any needed data to the view controller that is about to be displayed.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"StoryboardIDOfViewControllerThatWillBeShown"])
{
YourViewController *destinationViewController = segue.destinationViewController;
destinationViewController.dataToPass = _yourTextField.text;
}
}
The best practice is to give each segue in your storyboard an unique identifier. This identifier is a string that your application uses to distinguish one segue from another.
Here is the full description of Passing Data Between View Controllers.
I'm creating an app in Xcode that currently consist of a Navigation Controller a Table View Controller and a regular View Controller.
I'm using StoryBoard and have created a segue between the table view and the regular view controller. In the navigation bar I have a button that I've dragged to the view controller in the StoryBoard. When I click at the button, the new View Controller is viewed like it suppose to. I then tried to pass data from the table view controller, see below:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"läggTill"])
{
// Get reference to the destination view controller
AddPlayerViewController *apv = [segue destinationViewController];
[apv.myTextField setText:#"hello"];
}
}
The segue identifier is "läggTill", but the code inside the if-statement is not executing.
Two questions:
What is wrong with this approach?
Is this the best approach when using StoryBoards? Can I pass data via viewWillDisappear?
Can I use segues to pass data back to the table view controller from the view controller?
It makes all the sense in the world to pass your data in the prepareForSegue:sender:. I would not recommend passing data in viewWillDisappear because it just makes it messy and it reduces readability + it becomes harder to keep track.
I think your string comparison is not working! Put an NSLog for your identifier string see on the console. I have a feeling it might not like the "ä" character in comparison.
About your last question, as Gabriel.Massana pointed out, for passing data back, using delegate is the way to go.
Note 1: Another problem I noticed is a possible typo you might have "apv" and "avc".
Note 2: Another reason for it failing is that you are setting the TextField before viewDidLoad gets called on your destination controller. I suggest that pass it as string and in the viewDidLoad of your destination, set the text to your TextField.
I have view A with view controller A and view B with view controller B.
View A has a Container View which I've held down control + dragged to view B to make an association. At this point running the app shows view B inside view A's Container View
From view controller B I can programmatically change properties, but I'd like to change properties once it's loaded (or perhaps control the initialization of view B showing up in the Container View).
What I have is a wizard step (view B) and I want to highlight different icons based on the view that is consuming it, but I'm not sure how to call into the view controller B from view controller A (or if that's even the approach I want to take).
You can use prepareForSegue to get a reference to the controller in the container view from the main controller (controller A in your case). That controller will be the segue's destinationViewController, and prepareForSegue will be called as soon as the two controllers are instantiated (which happens one right after the other).
In your storyboard set an Identifier for the segue between A & B and then in Controller A add this code
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YOUR_IDENTIFIER"]) {
ViewControllerB *viewController = segue.destinationViewController;
viewController.property = value; // You can pass any value from A to B here
}
}
You could work with a single view controller that has the desired number of UIViews you want to have. This way you can control all the views from a single controller without needing to switch controllers. You can hide and show the views (and highlight the icons) according to your scenarios.
I've got an iOS app that has a page view to show multiple items as pages. Each page contains a tab bar controller with 2 tabs so I can show the info for each page in 2 ways - as a table or as a graph. Here's a screenshot:
So the user chooses which item to look at (in this case bananas) by changing pages. But I can't figure out where or how I should inject which item they're looking at into the 2 view controllers within the tab controller. Here's a shot of my storyboard if that helps. I want to inject it when the table view controller or graph controller are created but I can't see where that's happening to get at that code - have I missed something?
Thanks.
Not sure if this will work the same in the storybaord environment, but there is UITabBarControllerDelegate that has a callback method named didSelectViewController. It will give you the viewcontroller that is being selected. Doc from Apple.
If my understanding is correct, you should subclass your tab bar controller and implement the
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
method.
In there you can access the destination view controller by the segue object's destinationViewController property.
Depending on the segue identifier you can customise your destination view controller:
if ([segue.identifier isEqualToString:#"SegueID"]) {
MyViewController *myViewController = (MyViewController *)segue.destinationViewController;
//customize view controller
}
I'm trying to put together an iPad app using UISplitViewController and storyboards. The master view starts with a navigation controller linked to a table view of 6 menu options. Each cell in the table pushes a different table view controller onto the navigation stack. This is working fine for the master view. Each master view has a table list which when clicked needs to display a different view controller in the detail pane. I've currently done this with a segue set to 'Replace' and 'Detail Split' which works the first time a row is clicked, but as soon as you click another row in the master view, or rotate the device then the app crashes with EXC_BAD_ACCESS.
I'm fairly sure my problems are to do with how the delegate is setup for the UISplitViewController. I'm confused as to how this should be used when I have multiple master VCs and multiple detail VCs. Where should the delegate code be placed - master or detail? Do I have to implement the UISplitViewControllerDelegate protocol events in every view controller?
Any help appreciated.
If the split view controller delegate was the detail view controller that had been replaced, this is the cause of the crash. The replaced detail view controller is being dealloc'd and so the split view controller delegate is no longer a reference to a valid object.
You can update the delegate in prepareForSegue:sender:. For example:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
UIViewController *destinationViewController = [segue destinationViewController];
if ([destinationViewController conformsToProtocol:#protocol(UISplitViewControllerDelegate)]) {
self.splitViewController.delegate = destinationViewController;
}
else {
self.splitViewController.delegate = nil;
}
}
}
Which view controllers you use for delegates is dependent on your view controller hierarchy. In the simplest case, any view controllers that are assigned to splitVC detail will probably need to be delegates. You may want to base them all on a common super class that handles the shared split view controller delegate logic.