Search code examples
iosobjective-cswiftuiprogressview

Same UIProgressView Over Multiple View Controllers


PREAMBLE

I have an iOS application with a two page registration process.

I have installed a UIProgressView on each page to measure the cumulative progress of users within said registration process.

At present the registration process consists of six fields.

The existing UIProgressView takes a float input based on 1 / 6 updated when a text field finishes editing.

The first controller's UIProgressView launches with a float value of zero.

Once all fields are complete; the second view controller launches with a float value of 0.5.

PROBLEM

This solution is primitive and issues are abundant.

For starters you can see both UIProgressViews during unwind / segue.

QUESTION

Is it possible for me to use the same UIProgressView across the two view controllers ?

Thank you in advance for your help.

NB

The aforementioned registration process consists of two separate view controllers. Please advise if this is common practice / whether more suitable solutions exist.

MAIN ISSUE IMAGE UIProgressView Issue

Solving the issue illustrated within the image above is my primary objective.


Solution

  • If you want the progress bar to stay fixed while the user completes your 2 registration VCs, then use view controller containment.

    Create a parent view controller that contains the progress view and a container view to hold one of the 2 registration VCs. Use an embed segue to link that container view to a child view controller. You can make the child view controller a navigation controller if you like, or you can simply embed the first registration VC, then do the animation between the first and the second as desired.

    Edit: There's a method called transitionFromViewController:toViewController:duration:options:animations:completion: that lets you create transitions between child view controllers easily.

    Second Edit: If you need to communicate between the parent view controller and the child view controller(s), you have to wire up a way to do that yourself. To communicate from the child back to the parent the usual way to do this is to set up a delegate property in the child and define a simple protocol to communicate back to the parent. In the parent's prepareForSegue method you set the child's delegate property to self. The child can then send messages to the parent as needed.

    In your case you'd define a simple protocol that would let the child notify the parent about changes to the progress value, and then the parent would update the progress view. (It's a bad idea to have the child view controller manipulate the progress view directly.)

    If you want the parent to communicate with the child then you need to save a pointer to the child view controller as you set it up, similar to setting up a delegate.

    If you swap out the child view controller then you will need to set up the plumbing (child-to-parent delegate property and parent-to-child pointer) as part of the code that swaps child view controllers.

    I have a project on gitHub with the truly dreadful name "test" (link) that sets up a parent and child view controller, plus communications from parent to child and from child to parent.