Menu

Day 5 - Auto layout

Sep 02, 2015 at 09:23 am, by Pierre Liard

I spent quite a lot of time today on auto layout. It is a great Xcode feature that makes the layout appears as wanted, whatever the screen size of the iPhone or iPad is. It may be not so obvious the first time you have a try at it, but as soon as you have the hang of it, creating a layout is like a construction game. I will try explaining the process as I have understood it.

The first step is to prepare a draft of the layout. I will use the layout of "Prime number" as an example. I placed my elements approximately, but I made sure they were all vertically centered. I am also using the default view controller in the story board. It is valid for any size of screen. Before formatting anything, the draft needs to be previewed. At the top of the right panel, there is an icon with two intersecting circles. When clicked, it shows the assistant editor. On its menu, a click on the word "Automatic" opens another menu with, at the bottom, a preview section. The display should now look like that:

Unformatted layout

Despite I took care of aligning my elements, it is obvious that it is not the case in the preview. To center (or place the elements where you want them to be), it is necessary to use constraints or, in other word, margins. To add them is relatively simple, but it may be difficult, the first time, to find the related icons. They are located at the very right bottom of the view controller.

images constraint icons

They are so small that it is easy to miss them. The constraints commands are located in the two icons in the middle. The closest to the right is for the margins, and the one with the two horizontal bars is for alignment constraints.

To add a constraint, the related element has to be clicked first, then only the margins can be added. It is important to remember that the spacing is to the nearest neighbor. It means that the margins are relative to the closest element: it may be the external margins, as it can be another element in the layout. I cannot show here the entire process, but the display looked much better, after I placed margins and align the text horizontally.

formatted layout

The preview is a precious ally: it shows how well the elements fit in a vertical or a horizontal display. I would strongly advice to check the preview before adding any constraints. When those are set, it is a real pain to modify them. Auto layout and constraints features are used everywhere in an iOS layout. By using the library's elements, it makes possible to realize the layouts we are used to on our iPhones or iPads. I imagine that mastering all these tools requires practice and persistence, but a beginner can work with them quickly.

The last step of the prime number app was a breeze: simply copy and paste the code written yesterday, and adjust it to make print the appropriate messages in the app, instead of the console. The prime number app was the last chapter of the section four of this tutorial; it is a very important step to understand the fundamentals of Swift, but also the bases of almost any programing languages.

The chapter five "Navigation, Storage and Live Content" seems to cover quite a lot of ground. I am about to learn how to navigate from one screen to another, to store data permanently and as well downloading content from the web and using it into apps.

After showing us how to insert navigation and menu bars with bar button items into an app, Rob built the first app of this chapter, a stopwatch. It is at this point that I remembered how the Swift syntax may seem at times long and even wordy. Let's see in more details why.

When a new project is started, the ViewController.swift contains by default two functions necessary to build the app: a viewDidLoad and a didReceiveMemory warning function. Everything contained in the viewDidLoad will become active as soon as the app is running. In other words, if the stopwatch wants to be initialized, it has to be done when the app is first "fired". Swift uses a class NSTimer() to create a timer. To use this new timer, a method of the class NSTimer has to be called:

NSTimer.scheduledTimerWithTimeInterval (ti: NSTimeInterval, 
target: AnyObject, selector: Selector, userInfo: AnyObject?, repeats: Bool) 

questions marks

It is not obvious at all what this piece of code means and it is difficult to explain it without using an object oriented programming (oop) vocabulary. In my opinion, it shows the limits of this tutorial that doesn't often explain the concepts at stake. It's indeed a weakness that is counterbalanced by hand-on examples.

I have some programming experience, but imagine what would be your first reaction without coding knowledge. The only way to explain this code is to divide it in smaller parts. So bear with me: the newly created timer is in needs of some code to make it accomplish something.The section after NSTimer. is a method - a procedure associated with an object class (oop!) - and the elements in parenthesizes are parameters. The method's name is relatively self-explanatory: its purpose is to schedule a time interval. This interval is determined in the first parameter ti: NSTimeInterval, and targets an object that is generally the view controller itself. The third parameter selector: Selector is the method that will run when the timer hits the time interval determined in the first parameter, the fourth parameter - userInfo - is for now of no use, and the final parameter asks if we want the process to be repeated. Here is how the code looks like when the parameters have been inputted:

timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("result"),
userInfo: nil, repeats: true)

It is now more understandable: the timer is set to an interval of one second, its target is the view controller, a method named "result" will run when the timer hits one second, there is no user info, and the process will repeat itself.

Trying to dissect this code made me at least realized how this lengthy method is organized. It is also more apparent how this syntax is trying to self-explain itself and why it has been developed in this way by Apple. After this work of "decryption", the timer is almost ready to work, only the method showing the result has to be written. As with loops, a counter of some sort needs to be initialized to keep track of the time. A variable created outside of the viewDidLoad and NSTimer functions has a general scope because it is accessible from everywhere inside the app. If a variable is created inside a function, it's only accessible from this specific function. Before calling it a day, here is the final code of the stopwatch:

class ViewController: UIViewController {
   var time = 0 
   func result(){
      time++
      print(time)
   }
    override func viewDidLoad(){
        super.viewDidLoad() 
        var timer = NSTimer()
        timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:
                 Selector("result"), userInfo: nil, repeats: true)
 }

After the app is finished loading, the NSTimer class is called; its method - scheduledTimerWithTimeInterval - schedules the timer to run at intervals of one second and fires the function "result" that increments the counter and print the result in the console. When the app's layout is completed, only a few lines of code need to be added to make the stopwatch start, pause and reset at will.

What a day! I have covered quite a lot today and I have started better understanding how Swift methods have to be interpreted, all possible with this blog.


Leave a comment

Login to comment a post