Recently I tried something I had feared for a long time: Using code to create my views instead of using the traditional storyboard.
In any given iOS programming tutorial, you will most likely use storyboards to complete your task.
Now, there is nothing inherently wrong with using storyboards. They're perfectly fine and get the job done with creating your UI...
While the first part of my statement above is true, storyboards sometimes fall short when working in bigger projects with many view controllers or in views that have many elements and subviews.
My largest project right now had 20-30 view controllers in a single storyboard. Whenever I would open the storyboard, my ancient MacBook Pro would struggle to load the storyboard. I needed to rapidly iterate on my views based on changes in code and having the storyboard load time be 10 seconds+ wasn't an ideal situation.
Note: I later switched to using multiple storyboards which (mostly) eliminated this issue, however having multiple storyboards with storyboard reference outlets all over each of them is really confusing.
When a view controller in a storyboard has multiple views, selecting the correct one becomes difficult if they cover each other or reside as subviews. It is possible, but it's a tedious task that I wanted to avoid.
I also wanted to try something new, and killing storyboards sounded fun.
Code is great. And if I'm already using some code in my projects, why not go "full code"?
But wait... No storyboards = no visible view until runtime... How am I supposed to iterate quickly when I can't even see what I'm working on?!?
Ages ago, I read an article on how a fairly large app open-sourced and detailed their design iteration process. They used Swift Playgrounds to see the controller in real-time as they modified the code. Brilliant, let's do that!
Okay... so how do I use auto-layout and constraints without a storyboard? Through some research, I found out how to use constraints inside code.
Swift 3 Example:
let view = UIView() // Create view object view.translatesAutoresizingMaskIntoConstraints = false // Set this to false so this works as expected view.backgroundColor = UIColor.red // Let's set this to red so we can see where our view is in our controller self.view.addSubview(view) // Add our view to the view controller's view // View created, constraint time: view.heightAnchor.constraint(equalToConstant: 50).isActive = true // Let's break this down. // view.heightAnchor will set our view's height, as the name implies. // constraint(equalToConstant: 50) Will set the value to an integer constant of 50 // isActive = true will activate our constraint // Simple! Let's do the rest of the constraints: view.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 1/2).isActive = true // Set our width to be 1/2 of the view's size view.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true // Center horizontally on the X axis view.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true // Center vertically on the Y axis // And... done!
Let's take a look at our playground:
Awesome! Let's play around with these constraints and make our view appear at the top of the controller.
let view = UIView() view.translatesAutoresizingMaskIntoConstraints = false view.backgroundColor = UIColor.red self.view.addSubview(view) view.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 1/3).isActive = true view.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true view.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true view.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
Here I've used a new item: topAnchor
Setting it equal to the view controller's view's topAnchor (that's a mouthful!) will cause our view to reside at the top of the view controller's view.
I've also set our width to be equal to the view's width, centered our view horizontally, and set our height to be 1/3 of the parent view's height.
So cool! In just a few lines of code, we've created a view at the top of our view controller.
To learn more on how to use these constraints, I decided to take an existing view controller created in my storyboard and re-create it in code.
I actually ended up creating a simple view controller/tool called "AccountController" that can be easily modified to show a login and registration page. Neat!
Also, feel free to modify it as you wish, it's under the MIT license! I plan on fixing some issues and improving on it over time, but feel free to fix bugs and improve it for me via pull request!
Thanks for reading!
FYI, I'm only 15 (almost 16!) so if my grammar or wording is poor, I apologize :)