Search code examples
iosswiftuiscrollviewuistoryboardxcode-storyboard

iOS Storyboard Scroll View With Content Around View


In my application I have this view controller where the user inputs information to create an object pretty much. At the top of this view I have a tab bar and at the bottom I have a button that the user taps to create/save the object. In between those two views I have some elements such as text fields, labels, and a few other things that the user inputs the information of the object into, (basically a form for the object).

I'm now trying to support landscape mode as well as add a few more forms to this view controller. Problem is on smaller devices and in landscape all of the form elements and text fields, etc won't fit.

I'm trying to use a scroll view to solve this. I used this Stack Overflow answer to get the scroll view working in a test project (before I port the concepts to my actual project).

Only trouble is if I can't pin a button to the bottom of the screen using that method. To solve that I've created a container view inside of the main view controller (view controller A). That container view maps to the view controller (view controller B) that houses the scroll view and contents. Then right below the container view in view controller A I was able to add the create/save button. That seems to work perfectly from a design perspective. But now that the content is in a separate view controller from the create/save button I can't actually get the contents and inputs from what the user enters into the text fields.

What is the best way to handle a situation like this? Is using a container view really the best method here? Is there a simple way to map those inputs from the text fields back to the main view controller?

If possible I'd like to keep as much of the design work in the Storyboard as possible. Adding views and design elements in Swift would be a last resort. But I'm pretty sure I'll need to use some type of code to get that data back to the main view controller which is totally ok.


Solution

  • The easiest way for you to achieve the behaviour that you want is the following:

    1) Specify custom identifier for the embed segue which is created for you in IB. For example, "embedViewControllerB"

    2) In view controller A add the following parameter:

    weak var viewControllerB: ViewControllerB?
    

    3) In view controller A override prepare(for segue:) function. Check if the segue is your embed one and if so, store reference to the B controller:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "embedViewControllerB" {
            self.viewControllerB = segue.destination as! ViewControllerB
        }
    }
    

    Now when you click on your button you can get access to the contents of view controller B through the viewControllerB? property.

    At this stage it is up to you to decide how to proceed. You can either setup IBOutlets to the text views in B and read contents of them in A, or you can implement some function in B which would return the necessary data (maybe in a tuple?).

    Hope this helps