xcode

Implementing Dark Mode with macOS Mojave and Swift

With the latest macOS release, Apple introduced Dark Mode. Dark Mode changes the whole colour scheme of the OS to a darker, more subtle style. Not only does the OS change but so do the apps.

We recently added support for Dark Mode to Quids, our cryptocurrency Mac app. I was impressed with how easy Apple had made Dark Mode to implement and I expect to see a similar system come to iOS in the future.

If you have just used system colours such as NSColor.textColor, NSColor. selectedTextColor and NSColor.windowBackgroundColor, then your work is done!

However, you most likely have some custom colours. Here is an example of what our colour setup originally looked like:

internal extension NSColor
{
    internal struct Quids
    {
    	internal static let buttonBackground = NSColor(deviceRed: 250.0/255.0, green: 250.0/255.0, blue: 250.0/255.0, alpha: 1.0)
        // ... etc ...
    }
}

First step is to create a new Asset Catalog. Choose where you want to add the new file, right click, New File, Asset Catalog. Give it whatever name you want, I like to live on the edge and use Colors.xcassets.

Screenshot-2018-11-15-at-11.35.41

Next you need to add a colour set. Do this by either right clicking on the asset catalog’s left list view or by clicking the + button in the catalog’s bottom left and select “New Color Set”

Screenshot-2018-11-15-at-11.40.21

Now you’ll have something that looks like this:

Screenshot-2018-11-15-at-11.43.35

First things first, set the name. On the right side where it says “Name: Color” set this to whatever best describes your colour. I’m going to call mine ButtonBackground.

As it stands, this colour set is only setup as having no appearance, meaning that no matter what colour mode the user has, our ButtonBackground colour will always be the same.

On the right, select the “Any, Dark” appearance.

Screenshot-2018-11-15-at-12.01.58-1

You’ll see another colour swatch appear. Clicking a swatch will let you set the colour values:

Screenshot-2018-11-15-at-12.05.56

With the colours set, the last step is to update our code:

internal extension NSColor
{
    internal struct Quids
    {
    	internal static let buttonBackground = NSColor(named: "ButtonBackground")!
        // ... etc ...
    }
}

That’s it! We’re now all setup to use the colour in our app…

Using The Colour

If you’re using a standard control that takes an NSColor, for example NSTextField and NSWindow then all you need to do is set our new colour:

self.textField.textColor = NSColor.Quids.buttonBackground
self.window.backgroundColor = NSColor.Quids.buttonBackground

However, if you’re doing something a little more custom, like setting a CALayer’s background colour:

self.view.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColor

This won’t work. Never fear! There a few hooks that get called when the OS’s colour mode changes:

// NSViewController

override func updateViewConstraints() 
{
    super.updateViewConstraints()
    self.view.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColo
}

// NSView

override func updateLayer()
{
    super.updateLayer()
    self.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColor
}

override func layout()
{
    super.layout()
    self.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColor
}

override func updateConstraints()
{
    super.updateConstraints()
    self.layer?.backgroundColor = NSColor.Quids.buttonBackground.cgColor
}

Xcode 9.3 Simulator Freezes

For a few days I had an issue where every so often the iOS simulator would freeze when booting up. It would just display an activity indicator. Then I saw this Tweet and now all is fixed!

Weird Xcode install issues with unbootable simulators?

xcrun simctl erase all

resolved it for me

— Jason Kneen (@jasonkneen) April 30, 2018

Framework not found X for architecture x86_64

This error happens when I try to run tests when using Carthage

This has happened to me a couple of times now and I keep forgetting how to fix it. So I thought I'd write it down here.

In your test target, add this to the Framework Search Paths...

$(PROJECT_DIR)/Carthage/Build/iOS

Or if you're on macOS:

$(PROJECT_DIR)/Carthage/Build/Mac

🎉