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.
- Vertical Layout — Sub Views are laid out vertically one below the other.
- Horizontal Layout — Sub Views are laid out horizontally one after the other from left to right.
- A Combination of the above two layouts.
Create a Single View Application in Xcode and do the following in the viewDidLoad method.
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.
Add the code above to your project and edit viewDidLoad functions as below.
And run it in your emulator. You will get a screenshot as below.
Notice a couple of things.
- The vertical layout takes the height of it’s laid out components.
- 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
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.
Add the above code to your project and edit viewDidLoad to the following.
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.
Add the code above to your project and edit viewDidLoad to the following.
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.
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.