Want to offer native, in-app customer service to your users? Get going quickly with Zendesk’s Mobile SDKs. Free with Zendesk.

Active Filters: UIKit

UITableView & UICollectionView have some fantastic animation capabilities. We can animate items and sections being inserted, removed, moved, etc. We've all been there though, reloadData is sitting right there, and is conceptually so simple. Wouldn't it be great if we could enable those fancy animations in our views, with the conceptually simplicity of reloadData?

Today we'll check out Dwifft, a library from Jack Flintermann that can help us achieve this. Let's dive in.

We'll begin with a regular UITableViewController. (Dwifft works just as well on UICollectionViews).

First we'll need a TableViewDiffCalculator. This is a generic type, so we'll tell it that we're going to be display a bunch of Strings.

class ExampleViewController: UITableViewController {
  var diffCalculator: TableViewDiffCalculator<String>?

Next we'll initialize our data with some random items (just a randomly ordered array of Strings). We'll also use a property observer to let our diff calculator know whenever our items change.

  var items: [String] = ExampleViewController.randomItems() {
    didSet { self.diffCalculator?.rows = items }

We're almost there. We'll initialize the diff calculator in our view controller's viewDidLoad function:

  override func viewDidLoad() {

    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "ItemCell")
    diffCalculator = TableViewDiffCalculator<String>(
      tableView: tableView,
      initialRows: items

Lastly, we'll implement a couple of standard UITableViewDataSource functions:

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items.count

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
    cell.textLabel?.text = selfitems[(indexPath as NSIndexPath).row]
    return cell

Success! Here's how this ends up looking:

The "Shuffle" button was wired up off-camera, but it simply sets self.items = ExampleViewController.randomItems().

Now we can simply update the diff calculator's rows and we'll get all those beautiful, scroll-position preserving animations automatically.

A couple of final notes, we can customize the individual animation types like this:

diffCalculator?.insertionAnimation = .fade
diffCalculator?.deletionAnimation = .fade

And finally for fun the science behind Dwifft is pretty neat to read about. Read more about the Longest Common Subsequence Problem here.

Learn more about Dwifft at git.io/dwifft

Alerts have been around since iOS was iPhone OS. First in the form of UIAlertView, and now through UIAlertController (Bite #44). The built-in system alerts work great, but sometimes we want something fancier 🎩. Today we'll check out PMAlertController from Paolo Musolino, a library that allows us to easily display great looking alerts in our app. Let's take a look.

PMAlertController is essentially a fancier replacement for the styles that UIKit's UIAlertController already provides.

PMAlertController two styles of alerts: "Alert" and "Walkthrough".

The "Alert" Style is 270 points wide (matching the system's alerts):

The "Walkthrough" Style is almost the full width of the screen and is appropriate for more in-depth alerts/dialogs (such as those for explaining why our app is requesting permission for some of the user's data):

Using PMAlertController is almost just like UIAlertController.

We're given a title, description and image to work with:

let alertVC = PMAlertController(
  title: "Locate your device", 
  description: "Enables access to your...",
  image: UIImage(named: "flag.png"),
  style: .alert

  title: "Cancel", style: .cancel,
  action: { in }

  title: "Allow", style: .default,
  action: { in }

present(alertVC, animated: true, completion: nil)

We instantiate the view controller, add some actions (each with their own closure handler that will be called when the action is tapped), and present it.


Libraries like PMAlertController can help us easily add some polish to our apps, but they can also be a great way to learn about creating custom controls in general.

Learn more about PMAlertController at git.io/pmalert


#270: Implementing Theming with CostumeKit 🎩


We've looked at protocols in Swift in Bite #232, but we haven't really seen a ton of "real world" examples. Today we'll check out a library called CostumeKit. It's a set of base protocols that can assist us in visually styling or "themeing" our apps. Along the way we'll use some protocols "for real". Let's jump in.

Author's Note: Full disclosure, CostumeKit is written by me. I'm a huge fan of conventions, also it's a nice basic example of Protocols. I use it in all my apps.

To try this out, we'll be working on an imaginary Little Bites of Cocoa app.

We'll start by adding CostumeKit to our project with Carthage:

github "jakemarsh/CostumeKit"

Next, we'll start implementing our types. First up is the colors we'd like to use.

We'll make an enum and paste in all the colors we want to use, giving each a friendly name:

public enum LittleBitesColors : Color, ColorPalette {
  case beige = "FEFAF1"
  case lightBrown = "AB9372"
  case brown = "8C5637"
  case lightGray = "ECECEC"
  case darkGray = "6A6A6A"
  case sponsorRowGray = "F5F5F5"

Sharped-eyed-readers will actually recognize this technique from Bite #255 on Creating a ColorConvertible Protocol.

Moving along, LBOC uses the Source Sans Pro font. Let's implement CostumeKit's Font protocol for this. We'll add the font files to our app then implement the protocol:

public struct LittleBitesFont : Font {
  public init(size: FontSize = .textStyle(.body)) {
    self.size = size

  // Font

  public var size: FontSize

  // FontConvertible

  public var FontValue: UIFont {
    return UIFont(name: "SourceSansPro", size: pointSize)!

We're almost there, next we need to create the actual Costume our app will wear. For this we'll implement one more protocol. This protocol has no requirements. It serves as more of a convention really.

open class LittleBitesCostume : Costume {
  let spacing = CGFloat(8)

  public func wearRootBackground(_ view: UIView) {
    view.backgroundColor = Color.white.colorValue

  public func wearHeadline(_ label: UILabel) {
    label.font = LittleBitesFont(size: .textStyle(.title1)).fontValue
    label.textColor = contentTextColor().colorValue
  public func contentTextColor() -> Color {
    return LittleBitesColors.darkGray

  public var name: String { return "Default" }
  public var description: String { return "The default costume." }

  public init() { }

For good measure, we'll define a night-mode costume as well:

open class LittleBitesNightCostume : LittleBitesCostume {
  public override func contentTextColor() -> Color {
    return Color.white

  override public var name: String { return "Night Mode" }
  override public var description: String { return "For reading in the dark." }

That's where CostumeKit stops. We get a super-tiny bit of functionality "for free" (fonts, color parsing), but the idea is that we're merely following a set of conventions to help guide us through writing this code.

Let's finish up by looking at how we might actually use costumes in our app. Everything from this point on would live inside our app's code (and isn't part of CostumeKit).

We'll make a Wardrobe type and static instance to manage all our costumes:

import CostumeKit

public class Wardrobe {
  private(set) var current: LittleBitesCostume

  init(initialCostume: LittleBitesCostume) {
    current = initialCostume

  public func change(costume: LittleBitesCostume, animated: Bool = true) {
    // TODO: In the future, we'll animate this change using UIView transitions and RxSwift.

    current = costume

public let wardrobe = Wardrobe(initialCostume: LittleBitesCostume())
public var costume: LittleBitesCostume { return wardrobe.current }

Now in our regular UIKit code, we can use our current costume:

let headlineLabel = UILabel()
headlineLabel.text = "Hello World".

Learn more about CostumeKit at git.io/costumekit


#269: Taptic Engine Basics 👋


With the iPhone 7 and iPhone 7 Plus, Apple added a remarkable new piece of hardware to our devices. It's called the Taptic Engine and it is a big change from the old vibration feedback mechanisms we're used to. Today we'll look at how we can use it in our apps. Let's get started.

Haptic feedback on iOS is all about subtlety.

We want to help inform and/or guide the user, not annoy them. For these reasons, Apple has provided a few different classes we can use to generate haptic feedback that matches what we find around the system.

First up, UIImpactFeedbackGenerator. This is great for more prominent user interactions like when a part of our UI "snaps" into place (for example, imagine a drawing app that snaps when you drag over the exact center of the document).

Next, UISelectionFeedbackGenerator. These are perfect for small, subtle changes in selection. We can preview this one by 3D Touching on an app's icon on the home screen (one with a few 3D Touch shortcuts). If we keep our finger down and drag between the menu items, we'll feel the slightest "click" as we change selection. Neat!

Last, we have UINotificationFeedbackGenerator. These are pretty heavy and are meant for things like errors or warnings. (Imagine a login form that uses this generator when the user enters an incorrect password).

Now, lets try this out in code. First we need to instantiate a generator, and call the prepare function on it.

let generator = UISelectionFeedbackGenerator()

The prepare function is crucial here. It has to do with the physical hardware inside the device.

Basically, prepare will "wake up" the Taptic Engine hardware and put it into a state where it's ready to generate feedback immediately when we ask it to. iOS is relentless about saving battery and power. The Taptic Engine isn't always using "full" power, and only does so for a few seconds after the prepare function is called. Neat.

Things will still work if we don't call prepare, but they might not perfectly match up with the changes on screen (another crucial part of crafting effective Haptic feedback).

Now all we need to do trigger the actual haptic to "play" is:


Each generator has its own function for "playing" the haptic. (i.e. impactOccurred, selectionChanged, and notificationOccurred, respectively).

Finally, let's look at a "complete" example using a gesture recognizer:

var generator : UISelectionFeedbackGenerator? = nil

func panned(_ sender: UIPanGestureRecognizer) {
  switch(sender.state) {

  case .began:
    generator = UISelectionFeedbackGenerator()
  case .changed:
    if selectionChanged(translationPoint: sender.translation(in: view)) {

      // we call prepare again right after "playing",
      // to make sure the taptic engine is "ready" if the user
      // moves their finger again quickly.

  case .cancelled, .ended, .failed: generator = nil

  default: break



#268: What's New in Tab Bar Customization 🎨


Tab Bars have been around since the very first iPhone. They are a fantastic way to organize the top level screens in our app, and give users a quick way to get to each. Today we'll check out the latest improvements to how e can customize the look and feel of UITabBars in our app. Let's begin.

First up: Badge Customization.

For years we've had to resort to custom drawing or other methods to change how the badge would appear on a tab bar in our app.

In iOS 10, Apple has added a couple of features to allow us to completely customize how this looks with only a few lines of code.

Let's try this out. First, we'll set a badge value on one of the tabs:

func configureTabBar() {
  guard let tabBarItem = self.tabBarItem else { return }

  tabBarItem.badgeValue = "268"

Nice. Now let's customize that badge. All we need is one function and some attributes:

  NSFontAttributeName : UIFont(name: "AvenirNextCondensed-Medium", size: 14.0)
], for: .normal)


Next, we can now easily change the background color of the badge:

Lastly, we'll customize the tabs themselves using one final new feature, unselectedItemTintColor (Finally):

guard let tabBar = self.tabBarController?.tabBar else { return }

tabBar.tintColor = UIColor(white: 0.1, alpha: 1.0)
tabBar.unselectedItemTintColor = UIColor.lightGray



#263: Changing the Color of the Status Bar 🏴🏳


Today we're going to take a look at how to control how the status bar appears in our app. Let's get started.

The simplest way to change how the status bar looks in our app is to override preferredStatusBarStyle:

class SpaceshipViewController : UIViewController {
  override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent

The .lightContent style lives up to its name, as it makes the status bar's content white.

This work great until we put our view controller inside a navigation controller. Overriding the property then has no effect, as the system is actually asking the navigation controller.

We've all been here:

Yuck. Let's fix that up.

Since our content here is in a navigation controller we can use a "tried and true" approach that involves simply subclassing UINavigationController:

class LightStatusBarNavigationController : UINavigationController {
  override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent

To make this work, we can set this custom subclass in Interface Builder, or use it when creating our UI in code. Let's have a look now:


This approach works in our case, but might not be the best way to do this. If the navigation bar ever gets hidden, UIKit will actually start asking the contained view controller for the status bar's style, which may or may not be what we want.

We could have accomplished the same thing using a plain old UINavigationController by simply setting its barStyle property when we create it (or by setting this property in Interface Builder) to the .blackOpaque style:

let nc = UINavigationController(rootViewController: spaceshipsVC)
navigationController?.navigationBar.barStyle = .blackOpaque

Or, even better, we could set this style using UINavigationBar's appearance proxy, so this style is applied to all the navigation bars in our app:

UINavigationBar.appearance().barStyle = .blackOpaque

(A huge hat tip to Caleb Davenport for helping out with these techniques!)

That takes care of the screens in our code, what about when the app first launches though?

For this, we'll need to turn to our project's settings.

Here we can hide and show the status bar during launch, and change its color. Let's take another look:



#256: UIPasteboard Revisited 📋


UIPasteboard is a wonderfully simple little type with a ton of great functionality inside. (Covered previously in Bite #45). Today we'll check out the latest pasteboard improvements in iOS 10. Let's begin.

The biggest new user-facing feature of pasteboards in iOS 10 and macOS Sierra is the Universal Clipboard. This allows users to copy some content into their clipboard on one device, and retrieve it on another.

We don't need to do anything to get this functionality in our apps. This behavior is on by default for UIPasteboard.general, but we can configure how items behave when we add them.

Expiration Dates

let tomorrow = Date().addingTimeInterval(60 * 60 * 24)

  [[ "URL": URL(string: "https://littlebitesofcocoa.com")! ]],
  options: [.expirationDate : tomorrow]

Preventing Universal Clipboard

Sometimes there's going to be data that doesn't make sense to sync using the Universal Clipboard. This is easy.

  [[ "URL": URL(string: "https://littlebitesofcocoa.com")! ]],
  options: [.localOnly : true]

has* Properties

Last but not least, UIPasteboard has a few new helper properties for easily checking the current state of a pasteboard:

// we can check for images, URLs,
// strings, and colors this way
if pasteboard.hasURLs {

When using UIImageViews, sometimes the built-in content modes can cramp our style.

Many times, we're displaying photos of people. In these cases, it'd be great if the image view could somehow be told to intelligently crop the photo around the person's face.

Today we'll check out a library from Beau Nouvelle called AspectFillFaceAware. It's super simple, let's take a look.

AspectFillFaceAware is essentially just an extension on UIImageView. It provides two ways to configure an image view to be "face aware".

The first is in Interface Builder, we can enable the feature by flipping on the feature in the Inspector. (Not seeing the option? Run your project once, then it should appear).

Here's the how it looks:

We can also enable the functionality in code by setting the image view's image using this new function:

imageView.set(image: avatar, focusOnFaces: true)

We can even throw a quick corner radius on the image view's layer to try out the "face aware" functionality on a circular view. (i.e. user avatars):

let radius = imageView.bounds.size.width / 2.0
imageView.layer.cornerRadius = radius

Under the hood, the library is using a low accuracy CIDetector with a type of CIDetectorTypeFace to handle the actual face detection. Want to dive deeper here? We covered CIDetectors way back in Bite #87.

More info about AsyncFillFaceAware can be found at git.io/faceaware


#246: UITextField B-sides 📼


UITextField is one of the sort of "low key" hidden gems of UIKit. Today we'll look at some of the lesser-known things it can do and how to configure them. Let's dive in.

We'll begin by creating a text field and customizing its look and feel. First, instead of boring plain placeholder, let's spice things up a bit:

let placeholder = NSMutableAttributedString()

    string: "Spaceship ",
    attributes: [NSFontAttributeName : boldFont]

    string: "Name",
    attributes: [NSFontAttributeName : font]

textField.attributedPlaceholder = placeholder

Nice, now let's customize how our text field works.

Suppose we wanted to clear out its contents when a user tapped it. We simply set clearsOnBeginEditing to true.

Similarly, if we wanted to clear the contents not when the user tapped the field, but rather when the user began typing content, we can set clearsOnInsertion to true.

Let's add some more "padding" to our text field. This turns out to be a tricker than expected.

UITextField allows for customization of the rects it uses to draw text via subclassing:

class PaddedTextField : UITextField {
  override func textRect(forBounds bounds: CGRect) -> CGRect {
    return bounds.insetBy(dx: 16.0, dy: 8.0)

Finally, we'd like allow users to fancy up (bold, italic, underline) the names of their spaceships. Turns out UITextField makes this super easy:

textField.allowsEditingTextAttributes = true

With attribute editing enabled, we now get this great editing rich-text UI for free. Neat!

In Bite #241, we learned about all the great improvements to UICollectionView's cell lifecycle in iOS 10. Today we'll check out another iOS 10 improvement to UICollectionView: The prefetchDataSource! Let's get started.

UICollectionView gains a new property this year called prefetchDataSource. Just like the existing delegate and dataSource properties, we an simply set it to some object that implements the new UICollectionViewDataSourcePrefetching protocol.

This protocol is brand new in iOS 10, and requires we implement just one new function:

public func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath])

When this function is called, we can examine the indexPaths array we're passed in to know which cells are "coming up soon" and thus which cells we should probably begin loading the data for. The indexPaths will be ordered "ascending by geometric distance" which basically means the indexPaths that need to be displayed on screen soonest will be first.

Let's use this new functionality to let our UICollectionView pre-load the images that go in our cells, This way when they scroll on screen, the images will already be visible and won't have to "load in" in front of the user. Classy! 🎩

class SpaceshipsViewController : UICollectionViewController {
  override func viewDidLoad() {

    collectionView?.prefetchDataSource = self

extension SpaceshipsViewController : UICollectionViewDataSourcePrefetching {
  func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
    ImagePreloader.preloadImagesForIndexPaths(indexPaths) // happens on a background queue

  func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) {
    ImagePreloader.cancelPreloadImagesForIndexPaths(indexPaths) // again, happens on a background queue

That's literally it. We make sure to implement the optional cancelPrefetchingForItems function so that we don't waste resources preloading images the user won't actually see.

UICollectionViewDataSourcePrefetching doesn't replace our existing data loading architecture/functionality. It's essentially a hint as to which cells will be displayed soon, and which ones we might want to begin loading content for.

Finally, just like in Bite #241, we can opt-out of this new prefetching behavior by either simply leaving prefetchDataSource set to nil, or by setting isPrefetchingEnabled to false.

Oh one more thing: All of this works exactly the same on UITableView too now, thanks to the (almost identical) new UITableViewDataSourcePrefetching protocol.

Page 1 of 8