Making the most out of Storyboard in iOS

Nishan
3 min readMay 15, 2019

--

Everyone loves storyboard (Not everyone, but still…). Even though it has some quirks, I still find it as a great tool. As a developer, you should learn to create layouts programatically too but if you are using storyboard, here are some tips & tricks that i have been using to make the use of storyboard as pleasant as possible.

Tip 1: Use the same name as UIViewController class for its storyboard identifier.

Instead of creating a new name for storyboard identifier, use the same name as its corresponding class. For example, if the name of viewcontroller class is LoginViewController, make sure the storyboard id for that viewcontroller is also LoginViewController.

Then with magic of swift extension, You can create

extension UIViewController {    class var identifier: String {
return String(describing: self)
}
}

And, next time whenever you are instantiating a view controller, you can do

self.storyboard?.instantiateViewController(withIdentifier: LoginViewController.identifier) as? LoginViewController

Tip 2: Use multiple storyboards

If you have lots of viewcontrollers, refactor it to multiple storyboards. There isn’t a general consensus on how to use multiple storyboard. Some people create one per each screen whereas i advocate on creating one per each flow.

For example, if you are creating an ecommerce application and your checkout flow consists of 6 screens then you should definitely put all those screens on new Checkout.storyboard file.

Then you can use extension again to access all those storyboards.

extension UIStoryboard {    class var main: UIStoryboard {
return UIStoryboard(name: "Main", bundle: nil)
}
class var checkout: UIStoryboard {
return UIStoryboard(name: "Checkout", bundle: nil)
}
class var onboarding: UIStoryboard {
return UIStoryboard(name: "Onboarding", bundle: nil)
}
}

and use them as UIStoryboard.onboarding.instantiateViewController(withIdentifier: LoginViewController.identifier) as? LoginViewController in code.

Tip 3: Use the power of generics to create ViewController instance

Using Tip 1 & 2 along with swift Generics, we can create a pretty powerful way of instantiating a viewcontroller.

First we create a protocol named StoryboardInstantiable as shown below. Using where constraint, we bound this protocol to be used by UIViewController only.

protocol StoryboardInstantiable where Self: UIViewController {
static var storyboardIdentifier: UIStoryboard { get }
}

Any viewcontroller which conforms to this protocol can be instantiated from storyboard. Another benefit is that we can now easily identify the storyboard that this view controller is created on.

class MyAwesomeViewController: UIViewController, StoryboardInstantiable {

static var storyboardIdentifier: UIStoryboard {
return UIStoryboard.onboarding
}
}

Now create a generic class which creates & returns the instance of ViewController that you specify.

class ViewController<T: StoryboardInstantiable> {
class func instance() -> T {
let vc = T.storyboardIdentifier.instantiateViewController(withIdentifier: T.identifier) as! T
return vc
}
}

That’s it. If you have LoginViewController class with its design made on storyboard, you can easily instantiate it as

let vc = ViewController<LoginViewController>.instance()

If you try to create an instance of any view controller which do not follow the StoryboardInstantiable protocol, you get anice compile time error too.

Tip 4: Avoid Segue

I personally don’t like segue. If you use segue to denote the connection from one controller to another, you will need to provide a separate identifier for it. If you have multiple segue spawning from same controller, you will need identifier for each one. Also Most of the time it tend to create a spider web like mess and you spend more time on arranging the viewcontroller instead.

Instead, You can simply navigate to another controller programatically in two steps:

Step 1: 
let vc = ViewController<LoginViewController>.instance()
Step 2:
self.navigationController?.pushViewController(vc, animated: true)
// or
self.present(vc, animated: true, completion: nil)

Tip 5: Define UI properties in code

I prefer to set properties such as font, text color, background color, text etc in code instead of setting those in storyboard itself. As a result, if i want to change text color for all my labels, i can simply change it in one place in code. You can create a nested struct which contains all the styles, colors or fonts etc. Also, if you plan to support multiple language (Localization) then you will find it beneficial to set all the static text from code instead of storyboard.

struct Theme {

struct Color {
static let contentTitle = UIColor.black
static let contentTitle = UIColor.blue
}
struct Font {
static let regular10 = UIFont.systemFont(ofSize: 10, weight: .regular)
static let medium10 = UIFont.systemFont(ofSize: 10, weight: .medium)
}
}

You can now easily access it as Theme.Color.contentTitle or Theme.Font.regular10 and set it on your view.

These are few tips that i wanted to share with you guys so that you can make the most out of storyboard. Even though storyboard gets much hate in ios community, it is still a great tool for rapid prototyping & even designing complex views.

I would love to hear your opinion. Please leave comments. Thanks :)

--

--

Nishan
Nishan

Written by Nishan

Code, Eat, Sleep, Travel, Repeat

No responses yet