create ios app without storyboards using prettyconstraints

Create app without Storyboards using PrettyConstraints


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:

create new project from Xcode
Create new project from Xcode

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

create app without storyboards
Create new project from Xcode

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.

create app without storyboards using PrettyConstraints
Storyboard option in Project settings

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 :

Edit storyboard name in Info.plist
Edit storyboard name in Info.plist

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???

constraint errors
Constraint errors
Credits: https://tenor.com

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!

Create app without storyboards using PrettyConstraints
Hello World!!

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:

add package dependency
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:

swift package options
Package options

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

package targets
Package targets

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!


Like it? Share with your friends!

One Comment

Your email address will not be published. Required fields are marked *