How I Taught Myself to Code - Week 6

Tim Platt
Tim Platt
Sep 9, 2018 · 14 min read

What did I do this week?

I would summarise this week by saying that I went back to some Swift ‘basics’. I took a whistle stop tour through control flows, functions, optionals, classes, structures, enums, properties, initialisation and collections. I also got hands on with scroll views; a Swift ‘basic’ that I hadn’t touched prior to this week.

So, why back to basics? Firstly, I’m still a beginner and as my understanding of Swift evolves, it affords me to go back and further understand aspects of the basics that I didn’t grasp previously (or nuances/details I missed first time around). Secondly, there’s a lot I’ve skipped as I’ve jumped to more fancy stuff (i.e. using CoreML) and I therefore have knowledge gaps that I need to plug.

Tutorials

I started the week by signing up for a paid subscription to Ray Wenderlich as I’ve completed all of the Angela Yu’s tutorials that I’m currently able to. Plus, I appreciate how important quality resources are to my progression and Ray Wenderlich’s website is one of the most reputed.

Programming in Swift
I spent the first couple of days completing Programming in Swift by Jessy and Catie Catterwaul. I learned a couple of nifty things, for example if you create a custom type in Swift you can give it a description that appears when someone option + clicks the type:

This will then appear as follows when you option + click Person. I liked this as it helps others to understand your code.

Using `///` to create a custom type description.

I also learned about type aliases, which allow you to define an alternative name or synonym for an existing type i.e. you could use Volume instead of Int when you want to refer to a type by a name that’s more contextually appropriate. I like the idea of using them to make closures easier to read. For example, say we have a function that takes a closure as a parameter:

We can create a type alias for that closure:

We can then write the function above in a way that’s less verbose:

The above defines the type onCompletion to be the same as (Int, Int) -> Int. You could use the two interchangeably in your code moving forward. To clarify one more thing (as I didn’t understand the below):

var onCompletion = (Int, Int) -> Int is incorrect and will not compile. You can’t assign a type to a variable or constant.

var onCompletion: (Int, Int) -> Int is fine. You can declare a variable that has type: (Int, Int) -> Int.

There were two other stand out things that I learned about. The first was for in loops. Now, for in loops are one of the first control flows you learn about in programming but I’d not really covered them in Swift before (I assumed their syntax was identical to for loops in Java). If you don’t know about loops in Swift, then it’s a must learn as they’re used everywhere…Swift is a lot of for in loops, collection types and closures! So a few for in loop examples:

I actually much prefer Java’s way of doing for loops for(int i = 0; i < 10: i++) but perhaps my general preference of Java’s more verbose syntax will disappear over time!?

The second stand out topic I covered was collections. In Swift there are 3 main collections ‘out of the box’, these are arrays, sets and dictionaries (Java has a lot more). I should stress at this point that all tutors emphasise the importance of learning about collections and I’ve found that you pretty much use collection types everywhere so do invest the time! A collection type is essentially a container for values and each collection type has it’s own traits/benefits over another making them more suited to a particular task at hand.

The most interesting learning for me was how closures (see previous blog post) and collections can be use together in really powerful ways. For example, we can sort an array collection type using the sort(by: ) method, which iterates over an array and sorts the elements using a predicate that you pass in as a closure. The method takes a closure parameter and the closure parameter in the below is of type (String, String) -> Bool:

Interestingly, the closure type matches the type of the array that you use sort(by: ) method on. So if you sort an array of Integers, the closure would be of type (Int, Int) -> Bool. Awesome!

Using methods that take closures as arguments on collection types is often a cleaner alternative to using for in loops. So for example if we have a dictionary of people and their age, and we wanted to create a new dictionary of people older than 18, we could use a for in loop:

Now we could do this using the filter method and passing it a closure:

You can even chain methods. The example below sorts a dictionary in order of it’s keys, then it filters the dictionary to only include key:value pairs of people who are older than 18:

There’s a few methods worth getting familiar with when it comes to collections: filter, map, reduce, flatMap, compactMap and quite a lot of good material on the subject such as Santosh Botre’s or Abhimuralidharan’s articles.

Reproducing Popular iOS Controls
On Wednesday I started following the Reproducing Popular iOS Controls tutorials but I quickly found myself out of my depth. The project used complex storyboard layouts and scrollviews, the former I’ve not touched in that degree of detail before and the latter I haven’t touched at all. I did follow along and produced the animation below, but I can’t say I understood it (yet).

Scroll View School
So, I thought well why not educate myself on autoLayout and scrollviews and come back stronger? So I completed the Beginning Auto Layout tutorial (awesome) and Scroll View School. The former was super useful as I’d only scratched the surface in Angela Yu’s tutorial’s. The scrollview tutorial, well that I’m still wrapping my head around.

Firstly, I made my first scrollview (and also used gesture recognisers for the first time which involved weird #selector syntax which made zero sense):

Then I made a single page app to apparently help visualise frames vs. bounds (bounds I find tricky to wrap my head around). Doing well huh!?

Horizontal Paging UIScrollView Tutorial
Then, I decided I wanted to learn how to make an ‘on-boarding’ journey that are common on many apps (I assumed they used a horizontal scrollview). I’ve always found If This Then That’s on-boarding mesmerising:

That’s where I found this awesome tutorial by Anitaa Murthy. At first I didn’t understand the code, but then I spent the day dissecting it…printing variables to the console, change variable to see what happen when I ran the app, option + clicking different methods and properties. After a number of hours I fully understood the code; my persistence paid off.

I was even able to modify the code to add rotate the image relative to the amount the scrollview was moved by the user (the original project only scaled the image relative to the amount the scrollview was moved). I had to concatenate two transforms together to have the image both rotate and scale concurrently. The result was as follows:

A few key callouts/learnings from the ‘on-boarding’ journey above. Firstly, scrollView.isPagingEnabled = true is an amazing bit of code that makes the scroll view stop on multiples of the scroll view’s bounds when the user scrolls. In simple terms, it breaks the content up into screen sized chunks, to create a paging effect.

Another callout. When using scrollviews, you can implement the method scrollViewDidScroll which is called each time the scrollview is moved. You can find out how much the scroll view was moved both vertically and horizontally by using scrollView.contentOffset.x and scrollView.contentOffset.y. In the code below, we use the content offset to set the page index of the page control:

The code is basically saying… if the scroll view has moved by more than half the width of the screen, we’ve moved to the next page, otherwise we’re still on the current page.

Finally, to create the image scaling and rotation in the video we usedCGAffineTransform functions to create transformations with very little code. Transforms allow you to scale, rotate or move objects and views.

let translate = CGAffineTransform(translationX: 100, y: 100)
let rotate = CGAffineTransform(rotationAngle: 180)
let scale = CGAffineTransform(scaleX: 10, y: 10)

I spent 30 minutes reading Xiomara Figueroa’s blog on UI Animations in Swift and went from knowing nothing about iOS animations (and thinking they were probably impossibly difficult) to being able to create animations in relation to the movement of a scroll view. Epic! The code looks scary:

What it’s basically saying is… when scrolling between page the first and second pages, transform the images ‘scale’ relative to the amount that’s been scrolled. Then we concatenate another transform and ‘rotate’ the image relative to the amount that’s been scrolled.

Please don’t get stressed out by this code. It took me hours of tinkering to understand it. I still don’t actually fully understand the formula I wrote for the rotation 😂.

Reading

I read about two topics: properties and initialisation. I’ve previously glossed over these ‘basics’ in an attempt to maximise my time learning as much as possible. I assumed there wasn’t much more to these topics and what I learned from Java For Complete Beginners would allow me to get by, which it did.

However, as I tinker with more code I find myself seeing lot’s of syntax that I don’t quite understand; thus it felt like a good time to devote some energy to understanding properties and initialisation. BTW, I still don’t fully understand either topic, but I know a whole lot more and enough to be dangerous (in a good way). As always, I’m not going to write a tutorial about any of these topics in detail, but give an overview of the most salient aspects of my learning (… I do intend on writing more focused tutorials in the near future).

Properties
The Swift Language Guide states that, ‘properties associate values with a particular class, structure, or enumeration’. Properties can be stored i.e. store values in constants (let) or variables (var) or computed i.e. a value that’s the result of a calculation. Computed properties are provided by class, structure, and enumeration types. Stored properties are provided only by class and structure types. Properties can be associated with a type (i.e. a class) or an instance of a type (i.e. a class object).

In crude, simplistic terms… they’re the var and let values defined in classes, structures and enums. One thing to note… they’re not the same as global/local variables and constants i.e. a variable used in a for loop is a local variable. They’re specific to one of the 3 types mentioned.

The main things to know about stored properties is that if a value type is declared as a constant (i.e. structures/enums) then the var properties can’t be changed but this is not true for reference types (i.e. classes). So the below, would only work for a class instance.

Then there’s getters and setters (the code I’ve been finding confusing). Getters and setters are used to ‘get’ or ‘set’ a computed property and they’re written by putting a { after the property declaration (syntax that’s new to me); see below:

Now there’s a few ‘shorthands’ for setters and getters that really would baffle you if you didn’t read all about them like I have… honestly, it really pays to read the Swift Language Guide in its entirety. So first shorthand? Well you don’t need to define a name for a value passed to a setter as ‘newValue’ can be used in the braces by default. See below:

Another shorthand? If you only define a getter (i.e. you define a read-only property) then you don’t have to use the get keyword. See below:

Finally, the other main thing to know about properties is a thing called ‘property observers’. These are things that ‘observe and respond to changes in a property’s value’… willSet is pass the new property value and didSet is passed the properties old value. I imagine they’re useful to implement when you want to know if a property value has change i.e. if you have a gameCompleted: Bool property and want to be notified when the game completes without having to check periodically using a function. Again, willSet and didSet also have some shorthands that are worth knowing about.

So properties… you should learn about stored vs. computed, getters and setters and willSet and didSet property observers and you’ll have a good broad handle on them!

Initialisers
According to the Swift Language Guide, ‘Initialisation is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup’.

To perform initialisation we use initialisers, which are ‘like special methods that can be called to create a new instance of a particular type…their primary role is to ensure that new instances of a type are correctly initialised before they are used for the first time’.

We actually used one earlier…a default initialiser:

let newPerson = Person(firstName: "Tim", age: 29)

So, what’s the key stuff to know when it comes to initialisers? As already stated, classes and structures must set all of their stored properties to an initial value by the time an instance of them is created; this can be done within an initialiser or by using default property values when defining properties.

The below is a typical example of an initialiser that sets that properties of a type using the values passed into the initialiser as arguments when creating a new instance of that type, which in this case is a structure call Color.

Swift provides a default initialiser (hidden to you) if you don’t define an initialiser yourself and so long as you provide default values for all of your properties. Structures also get a ‘memberwise initializer’ if you don’t define an initialiser yourself - this is the case even if you don’t provide default values either (don’t ask)!?

Initialisers can call other initialisers to perform part of an instance’s initialisation. This is called initialiser delegation, this is illustrated by the self.init() code within the second initialiser. The second initialiser takes a ‘center’ parameter and then users that to call an initialisers that takes an ‘origin’ parameter to fully initialise the Rectangle Structure.

When it comes to structures and enums, delegation can only happen horizontally as they don’t support inheritance, unlike classes. If you have a parent/child classes then initialisation gets complex… seriously, there’s so much to read on the Swift Language Guide. However, a simplification below:

Food is the parent class and has an initialiser that sets the property ‘name’. RecipeIngredient is a child class and has an initialiser which sets the property ‘quantity’ of the subclass and then calls the initialiser of its parent class, passing it the name value. There’s a lot more to it, but from what I can tell, this captures much of the essence.

Read about initialisation in all it’s glory here.

Coding Challenges & Puzzles

I didn’t do any… I guess my big ‘challenge’ was decrypting the horizontal scroll view code and tweaking it to make the image rotate relative to the scroll. I’ve had a busy week OK!? 😊

What were the highlights?

  1. Understanding Complex Code Through ‘Play’. Much like a toddler learning about the world around them through play… I did the same but for learning about code. Also, by play I mean.. changing values and running the simulator over and over, printing everything to console, option + clicking everything. I learned an important lesson this week; if you don’t understand something then print it to console, then change it, then print it to console. Get hands on with the thing you don’t understand!
  2. Creating a Slick Onboarding Journey. I felt for the first time like I’d created (well replicated) something not to far from what you’d expect to see in a production app.
  3. Beginning to Remember How to Do Things. I have an awful memory, I really do, so it’s always feels rewarding when I remember something. I don’t have a specific example but there were a few times this week where I just did little things that I’d apparently learned like using optional binding to unwrap an optional or setting a constant as a delegate. There are a lot of things I don’t remember perfectly, but have learned enough to brute force my way to working code i.e. when writing the code to filter a dictionary above, it took me 30 mins to do it without Googling… but I got there! Most importantly, I’ll get there more quickly next time… and the time after.

What were the biggest challenges?

  1. Conceptualising Frames & Bounds. It took me ages to understand bounds. I watched the tutorial over and over again and I didn’t feel like I got any closer to understanding the concept. It was frustrating to produce working apps that demonstrated scrollviews diligently, without actually understanding how it was working behind the scenes. I’m constantly finding that the quality of the resource and teacher makes all the difference when it comes to learning about concepts. The second answer on Stack Overflow was the best explanation I eventually found.
  2. Maths. There was a lot of maths when it came to scroll views. It was simple math i.e. subtract 100pts (offset) from co-ordinate x (450pts) etc, but sometimes it’s hard to piece it all together. You have to know take into account the phones width, understand if scrolling left/right adds or takes away from the offset and move content by an amount relative to the scroll offset. It looks scary a first but they key is to just roll your sleeves up and keep running your code to see what happens!
  3. Lack of a Project. This week… I’m finding myself a project. I already have an ARKit project lined up but I need one I can work on now! I have plenty of ideas but none that totally captivate me… that will keep me up at night and spark a healthy obsession. I think to get better at coding, I need to work on a project to learn to solve problems myself vs. regurgitating what I see on a tutorial video.

Summary

I enjoyed working with scroll views and have some more advanced things I’d like to do with them at some point. Firstly, I’m keen to create some kind of parallax scrolling app similar to the If This Then That example in one of the videos above. Secondly, I have an idea which involves moving scroll view B in a different direction to scroll view A when (+ at a speed that’s a multiplier of A), when scroll view A is scrolled… the below image kinda gives an idea of how I’d like to lay those scroll views out:

I’m also realising that my life has turned into product management, coding in my spare time, a cat called Clementine and mountain biking… but I’m OK with that!

Much Love,
Tim

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade