Yearly Archives: 2015

How to access values in a Swift Dictionary

Swift has its own dictionaries, much like Objective-C has the NSDictionary class. Although the two are bridged, they are not the same: trusty old NSDictionary methods do not work with Swift Dictionaries.

Here’s a quick summary of how Swift Dictionaries work.

Creating and iterating over Swift Dictionaries

Let’s create a Swift Dictionary and then list all its values using Fast Enumeration:

The easiest way to create a dictionary is Option 3, letting the compiler infer everything. The other two options are valid too.

What’s special in comparison to NSDictionaries is that in Swift, we can pass both the key and the value to the for loop, rather than just the key.

Accessing a single key’s value

What the elaborate Apple documentation doesn’t explicitly mention for stupid people like me is how to access a single value in the Swift Dictionary. It’s surprisingly simple:

Changing a value in our dictionary

We can use the same syntax to update a value in our Swift Dictionary too. Notice that the dictionary must be declared as a variable rather than a constant. The compiler is nice enough to offer this service free of charge:

Adding key/value pairs to our dictionary

To add another key/value pair, we’ll pretend it already exists and simply set its value:

Counting all entries in the dictionary

To see how many key/value pairs we have in our dictionary, we can call the count method:

Clearing out a Swift Dictionary

To empty the whole dictionary from all keys and values without destroying the whole thing, we can use this:

This is different to setting the dictionary to nil because it leaves the key/value types in place (here: String and String).

Further Reading

How to present a view controller on top of a UISplitView Controller – Part 2

The second part of this mini-series about presenting another UIViewController on top of a UISplitViewController in iOS 9 and Xcode 7.

Check out the first part here, complete with code snippets and a link to the full project.

Enjoy!

Watch the full course in one convenient playlist:
Catch this episode on my iOS Dev Diary Podcast:

How to switch root view controllers in Swift

Here’s how to switch root view controllers in Swift. It comes in handy when you want to instantiate a view controller from your storyboard and display it at arbitrary points in your app.

Imagine a single view application with an additional view controller. Each view controller has a button that switches to the other view controller. To make it more interesting, each view controller is embedded in a navigation controller. The methods to switch to either view controller are called centrally in the AppDelegate.swift file:

In our storyboard, let’s make sure that each navigation controller has a Storyboard ID for manual instantiation. In the above example that’s One and Two respectively.

To call the first method from our first view controller, we’ll do this:

We’ll grab a reference to our UIApplication’s delegate and typecast it to be an instance of AppDelegate. Unlike in Objective-C, there’s no need to import this class into our view controller in Swift. Then we go ahead and call the method.

In our second view controller, we’ll do exactly the same, except for calling the other method in AppDelegate:

Here’s a demo project that shows the above in action:

How to prevent the screen from sleeping in iOS

Screen dimming getting on your nerves? That rancid 5min timeout not enough for testing, or does your app need to stay awake while it’s in the foreground?

Fear not, UIApplication has a parameter we can set to prevent an app from going to sleep, or the screen from going dark. We can set this anywhere in our app:

To make the display adhere to whatever the user has set again, simply change the parameter back to NO.

How to present a view controller on top of a UISplitView Controller – Part 1

SplitViewDemo

Since its introduction in iOS 5, our good friend the UISplitView Controller has always had a really annoying habit: it has to be the root view controller in our apps. This means that it cannot be presented from any other view controller, nor can the split view controller present other view controllers.

This sucks because 99% of all apps probably need to present a user choice overlay at some point during the lifetime of an app. While some apps may get away with showing a Popover on iPad, many apps would be better off if we could present something like a proper form sheet as pictured in the image above. However, by Apple’s definition, that’s just not possible with the split view controller.

Or is it…?

In this screencast I’ll show you how to make it appear as if we could present another view controller over a UISplitView Controller. We’ll employ a bit of magic to create a great user experience, and it’s not really difficult either. The whole thing works on both iPhone and iPad with no extra work, and it works with apps in Slideover Mode too.

At the bottom of the article I’ll show you the code snippets to make this magic happen, together with a fully working demo project.

Enjoy!

 

Code Snippets

The app is based on the Xcode Master/Detail template. Aside from hooking up two buttons to present and dismiss the overlay, all methods are conveniently called in AppDelegate. We need three methods in total.

The first one will create a screenshot of whatever is currently on screen and return it as a UIImage:

I’m explaining how this method works and what it does  in this article.

The next two methods need to be public, so let’s make sure their signature appears in our AppDelegate.h file, anywhere before the @end:

Back in our AppDelegate.m file, here’s the first method:

Here we grab a screenshot using our previous method and create a brand new view controller with it, using the screenshot as a background. Because this is a standard UIViewController, we can present another view controller over it.

While the screenshot is one ingredient to our magic, switching root view controllers is the other: we switch out the split view for our standard view controller (the “fake split view”) using self.window.rootViewController. This is only possible from the AppDelegate because it has access to the main window of our app. Switching is instantaneous and – as long as the content is the same – invisible to the human eye. Before we do this, we’ll grab a reference to the split view so we can bring it back in our next method.

Our third method will dismiss the overlay again:

Here we dismiss the overlay and swap back to the split view controller we’ve grabbed a reference to earlier. We’ll do that in the completion block to make sure the animation has finished so nobody will notice what we’re doing.

To finish off the magic presentation, we’ll call the showOverlay method from our master view controller with a 0.2 second delay. This will allow the button animation to finish before we take the screenshot, otherwise our app will take a capture with the “depressed” button. That’ll look unhandsome when we switch back to the real split view.

Here’s how we do this “delayed firing”, via two methods in our MasterViewController.m file:

The first method is called when the user presses the actual button. All it does is wait for 0.2 seconds using an NSTimer. When the wait is over, it’ll call the second method, which in turn asks the AppDelegate to perform our showOverlay method.

The end result is a seamless user experience, and it appears we’re presenting the overlay right over our split view. Is this cool or what?

Demo Project

Here’s the full project I’ve built in the screencast:

Watch the full course in one convenient playlist:
Catch this episode on my iOS Dev Diary Podcast:

Building a searchable UITableView in iOS 9 – Part 4

In this final part of our project we’ll finish off the app by implementing a little Key Value Observation magic. This will let us update our second UITableViewController when new search results are to be displayed.

Check out the first part here, as well as a link to my demo project.

Enjoy!

Watch the full course in one convenient playlist:
Catch this episode on my iOS Dev Diary Podcast: