Back when I was developing my first app with Storyboard, I thought, life is smooth. Then my manager added a team member to the project, according to the ‘9 developers can deliver a baby in 1 month’ rule. Anyways, this mate did some work on the same storyboard I was working on and bam! Solving these conflicts, I made a promise to myself that the next project I create will not have a single storyboard in it! If you have been through the same, or due to some other reason, and you want to create a project without storyboard then you are at the right place! Let’s create app without Storyboards using PrettyConstraints!
Create app without Storyboards
Let’s create a new iOS app from Xcode. Open Xcode and create new project:

Choose App
and click Next
, you will see the following window:

Add Product name and other information, select Storyboard
for Interface
and UIKit App Delegate
for Life Cycle
, hit Next
.
Your project is now created. Great!
To get started, let’s delete the Main
Storyboard first!
From the Project Navigator
select Main.storyboard
and hit delete
, select Move to Trash
!
Now open Project Settings
, in General
under section Deployment Info
locate dropdown for Main Interface
and just clear the textfield.

Since the latest Xcode projects have SceneDelegates, we need to update that as well in our Info.plist
.
Open Info.plist
, and expand the Application Scene Manifest
section till you see an option for Storyboard Name
:

Delete the row for Storyboard Name
and you’re done there!
Now head to your AppDelegate
file.
Create variable to store the window if it’s not already created, (as the latest xcode uses SceneDelegate
) and add the following code in application(_:didFinishLaunchingWithOptions:)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
//...
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = ViewController()
window?.makeKeyAndVisible()
//...
return true
}
Great! This will add support for the iOS versions lower than iOS 13.
Now head to your SceneDelegate
file and add the following code inside scene(_:willConnectTo:options:)
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// ..
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = ViewController()
self.window = window
window.makeKeyAndVisible()
}
//..
}
Awesome! So now if you run your App, you will see a black screen!
Whaaat? Black? Hold on a minute, let’s configure our ViewController
first!
Create views programmatically
Let’s create a state of the art, “Hello world” label, to show in our ViewController
.
Add following code in your ViewController
:
let label:UILabel = {
let label = UILabel()
label.text = "Hello World"
label.font = UIFont.systemFont(ofSize: 16)
label.textColor = .black
return label
}()
Now let’s add this to the view
by adding the following code in your viewDidLoad
method like this:
override func viewDidLoad() {
super.viewDidLoad()
// ..
self.view.backgroundColor = .white
self.view.addSubview(label)
// ..
}
Here comes the devil that we introduce to get rid of storyboards, layout constraints!
In storyboard, we just click a button and give some constants, there you have your constraints, go!
Since we don’t have storyboards, this bad boy is gonna need some extra code to work!
Following the Old / Traditional way, let’s add constraints to our label
to display inside the view
:
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
self.view.addSubview(label)
NSLayoutConstraint.activate([
label.topAnchor.constraint(greaterThanOrEqualTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
label.leadingAnchor.constraint(greaterThanOrEqualTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10),
label.trailingAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10),
label.bottomAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10),
label.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor)
])
}
Here we have added constraints to show the label in the center of the view.
Cooool, now go ahead and run your app!
Whaaat?? Didn’t work yet??? wait, what are these errors???


Oh man! As always, I forgot to add this line before adding the constraints:
label.translatesAutoresizingMaskIntoConstraints = false
Now run your app and you should see the “Hello World”, finally!

So if you were with me this whole time, you know this is not helping us out!
Why do we need to write so much code to add constraints, set translatesAutoresizingMaskIntoConstraints
to false
everytime and have to activate these constraints manually?
Oh it’s just one label yet, we didn’t even add any other view or constraint to other subview. Try it and you will loose the interest even more!
What if I tell you I have got a solution for all of these and many more complexions?
YES! PrettyConstraints is the angle we need!
Constraints using PrettyConstraints
Let’s use this amazing pod we have created after 2 years experimentation with constraints!
Let’s add the Swift Package for PrettyConstraints in your project:
Go to File > Swift Packages > Add Package Dependency
:

In the window that opens next, paste this url and hit Next
:
https://github.com/mobiraft/PrettyConstraints
After verifying you will see the following window. Hit Next
:

This will start downloading the Swift Package and add it to your project.

Hit Finish
! As you just saw, Swift Packages are super easy to use!
Now let’s import the package:
import PrettyConstraints
And replace the unnecessary code with the shortcuts of PrettyConstraints.
Our updated viewDidLoad
should look like this:
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
self.view.addSubview(label)
label.applyConstraints(.top(to: view.safeAreaLayoutGuide.topAnchor, constant: 10, equality: .greaterThanOrEqual),
.leading(to: view.safeAreaLayoutGuide.leadingAnchor, constant: 10, equality: .greaterThanOrEqual),
.trailing(to: view.safeAreaLayoutGuide.trailingAnchor, constant: -10, equality: .lessThanOrEqual),
.bottom(to: view.safeAreaLayoutGuide.bottomAnchor, constant: -10, equality: .lessThanOrEqual),
.center(in: view))
}
That’s it, run your app and you should be able to say “Hello world!”
PrettyConstraints take care of all of our hassle of adding constraints, activating it, setting the view’s translatesAutoresizingMaskIntoConstraints
to false
, and constraints storage is an added advantage!
Example Usage of PrettyConstraints
// Constraint to anchor
label.applyConstraints(.top(to: self.view.safeAreaLayoutGuide.topAnchor))
// Optionally, Add custom padding
label.applyConstraints(.top(to: self.view.safeAreaLayoutGuide.topAnchor, constant: 10))
// Optionally, Add custom equality
label.applyConstraints(.trailing(to: self.view.safeAreaLayoutGuide.trailingAnchor, equality: .lessThanOrEqual))
// Center in view
label.applyConstraints(.center(in: self.view))
// Fit edges in view
label.applyConstraints(.fitInView(self.view))
// Fit in safe area
label.applyConstraints(.fitInSafeArea(self.view.safeAreaLayoutGuide))
// Constraint Width/height to height/width
label.applyConstraints(.width(to: label.heightAnchor))
// Constant width/height
label.applyConstraints(.height(constant: 50))
Conclusion: Creating app without storyboards using PrettyConstraints is faster and easier!
That is all on how to create app without storyboards using PrettyConstraints!
Checkout this handful tool here: https://github.com/mobiraft/PrettyConstraints
Checkout another quick article on How To Add Splash Screen in SwiftUI.
If you want to learn how to use SwiftUI
in your existing app, then you can read it here!
or If you want to learn how to use and convert your UIViewControllers
in SwiftUI
, then you can read it here!
One Comment