It is common in iOS development where UIViewController becomes very messy and hard to manage because it is filled up with every single element, including Views, outlets, actions, cosmetics, layouts and business logics.
In fact, UIViewController should be very simple. It only need to manage the Views and observe the actions occur. In this tutorial, I would like to share one of the best practice that I always apply to my projects.
We are going to break down the screen into multiple UIView components and each UIView component will manage all the layouts and styles themselves. It also will take a responsibility to notify ViewController of any action or changes. Besides, the UIView component eventually becomes reusable throughout the projects. Awesome!
Imagine we are going to develop this simple profile page (image above). So, in our mind, surely we are going to put all those things in a ViewController. We can simply open storyboard and start adding the outlets (Labels, Image) and some constraints. Exactly, that’s the common practice we always do, unfortunately 😅
Yeah, perhaps we won’t repeat such mistake again after finish reading this.
The problems will happen when start making more changes to the UI or maybe add more functions. Hence, the ViewController will be getting fatter easily.
Break it now
Now, we want to keep the UIViewController always slim and start breaking into separate UIViews. Here are the steps.
- First, add UIScrollView and UIStackView in ViewController to enable dynamically adding components.
- Separate into 3 UIViews (
- Create xib and UIView file for each component (You may create those programatically as you want)
- Manage all styles in each UIView.
- Create function in UIView to update UI with data.
- Add protocol (delegate) in each UIView to enable ViewController get events on any UI updates or actions
OK. Let’s get our hands dirty! Create a new iOS project. Before start going through each step, take note that you may refer the completed project uploaded here.
1 — Add StackView in ViewController to enable dynamic adding component.
Go to ViewController.swift, then add
UIScrollView() variables programatically (No need to touch the storyboard for now). First, add a UIScrollView and pin it to edge of superView. then we add UIStackView inside the scrollView and also pin the edges. Also make sure to set
width constraint of the stackView to scrollView.
Good! nothing changed for now if we run the project.
2 — Break down into 3 UIViews ( HeaderView, StatsView, and PostView)
In this step, we are going to create 3 UIView Swift files and 3 xib files, then linked it together.
a. HeaderView.swift and HeaderView.xib
Make sure to link the “File’s Owner” with “Class” name. Also link all
IBOutlets created in HeaderView.swift.
b. StatsView.swift and StatsView.xib (Same as before, to link the “File’s Owner” and Outlets).
c. The last
UIView file to create is PostView.swift and PostView.xib.
4 — All styles are manage in each UIView
5 — Create function in UIView to update UI with data.
Make sure to pass the proper object to be used. In this project, we will be using
DemoProfile with all properties required.
For step 4 & 5, we already did in step 3. Great!
6 — Add protocol (delegate) in each UIView so Controller can get events on any UI updates or actions
Perhaps you are familiar with Swift protocol since we are using it in this step to make sure UIView component able to notify ViewController on any action or changes.
Our UIView component is an independent class, therefore, ViewController won’t know anything that happen inside it.
In our case, we only need to add a protocol (delegate) in
HeaderView to notify Controller if the “Edit Profile” button is tapped.
a. Firstly, add a protocol namely
HeaderViewDelegate in HeaderView.swift
b. Then, as shown above, add a method called
didTapEditButton(). Then, make sure the button target action will call the delegate method (above code in line 19).
ViewController class, implement the
HeaderViewDelegate and set HeaderView object
self to get the call in the implementation method (as show below).
HeaderViewDelegate implementation in ViewController.swift file (at bottom) to make it works and avoid the error.
At last, let’s update the
ViewController to include those 3 components in the stackView. The updated
ViewController will be as below.
Congratulations! Now, we have completely done all the steps and the project is ready to run. See that our ViewController.swift is only got 52 lines. Really? Yeah and you did it 🎉.
The complete source code can be downloaded here. Try to implement into your existing projects so it will become cleaner and more extendable (with the future modules or features).
Thanks for reading and don’t forget to share with your friends. Feedbacks are most welcome.
“Learn, that’s how we grow our skills”