Dynamic Layouts in Swift

All the code in this article is available as a Github Project. https://github.com/santoshrajan/LayoutSwift

In Swift we use the Objective-C UIKit framework to layout components on the screen, using Storyboard, Constraints etc. In this article we will explore the possibilities of creating layouts without using Storyboards and Constraints, in Swift.

Most layouts will fall into one of the following three categories.

  1. Vertical Layout — Sub Views are laid out vertically one below the other.
  2. Horizontal Layout — Sub Views are laid out horizontally one after the other from left to right.
  3. A Combination of the above two layouts.

Create a Single View Application in Xcode and do the following in the viewDidLoad method.

https://gist.github.com/santoshrajan/e5f798b7a00e1bf19788

And run it in the simulator and you should see something like below.

Few things to note here. The ViewController has a UIView object called view whose width and height are set to the full screen. (Gray Color). We also printed to the console the view’s frame. You should see the following in your console.

(0.0,0.0,320.0,568.0)

The above is for iphone 5s. The frames origin is (0.0,0.0) and width and height is (320.0,568.0).

The sub views are laid out relative to the superview. The problem with laying out sub views this way is that you need to know the absolute positions and you have no control over laying out on other screen sizes.

Vertical Layout

A vertical layout lays out it’s subviews one below the other. Each subview is placed relative to the base line of the previous view. The vertical layout has a fixed width and a variable height.

We can create a vertical layout by extending the UIView class. The code for the vertical layout is given below.

https://gist.github.com/santoshrajan/58b399b0b6a7a60a72d4

Add the code above to your project and edit viewDidLoad functions as below.

https://gist.github.com/santoshrajan/1203611aed83c9105a39

And run it in your emulator. You will get a screenshot as below.

Notice a couple of things.

  1. The vertical layout takes the height of it’s laid out components.
  2. The second view (veiw2) is positioned relative to the bottom of view1. (100, 50, 100, 100). Whatever the height and position of view1, view2 is place 50 pixels below view1.

Now rotate the view. And we have a problem. The vertical layout has its width set, but we want it to take the full width of the screen. Below is a Vertical layout that will always take the full width of the screen.

The VerticalScreenLayout

https://gist.github.com/santoshrajan/58bbb2aa3b06343d7746

The VerticalScreenLayout sub classes the VerticalLayout and always takes the full screen width. Add the code above, to your project, and edit the the line that creates vLayout to

var vLayout = VerticalScreenLayout()

Now run the program and rotate the screen, you see VerticalScreenLayout taking the full width of the Screen.

The VerticalFitLayout

The VerticalFitLayout will expand the layout to fit the height of the parent view. One of the subviews MUST have its height set to zero. And the other subviews MUST be initialised with a height greater than zero. The subview with height zero is expanded to the rest of the height of the parent. Also the total height of the rest of the subviews must be less than the parent height.

https://gist.github.com/santoshrajan/09dd69257a53b183a1a2

Add the above code to your project and edit viewDidLoad to the following.

https://gist.github.com/santoshrajan/b517bcd65eb25cefa9a6

And your screenshot should look like this.

The HorizontalLayout

The Horizontal Layout takes a fixed height and lays out it’s subviews horizontally. Here is the code.

https://gist.github.com/santoshrajan/eb0988c460589f07beb5

Add the code above to your project and edit viewDidLoad to the following.

https://gist.github.com/santoshrajan/27d9456f82a882e0982f

When you run your program you should see the following.

The HorizontalFitLayout

The HorizontalFitLayout works like the VerticalFitLayout horizontally. The code is available in the github project. Here is the example usage.

https://gist.github.com/santoshrajan/71546afd60b64f25bde5

And here is how the above code looks on the simulator.

Note: These layout are not fully implemented, so you have to be careful of the following, if you use them. You cannot insert or remove subviews once the layout is set. If you need to do that, you will have to remove all the subviews and redo the layout again. You can use the removeAll function for that.

However I find a combination of these layouts very useful for my projects and they easily solve most of my layout problems.

An App Using the above Layouts

Here is an App (A Twitter Client) that uses the above layouts. Actual ScreenShot from my phone.

The whole screen is a VerticalScreenLayout, which contains a HorizontalLayout, UiTextView, HorizontalLayout Centered, UIImageView. The first HorizontalLayout contains a Vertical Layout within.And below is an image of how it is done.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.