UserInterfaceLevel, the future of floating apps?
Tags: swift, ios, programming
Published: 2020-06-07 23:03:34

---
title: UserInterfaceLevel, the future of floating apps?
published: true
description: Using iOS 13 newest TraitCollection property to add more dynamism to your apps.
tags: swift, iOS, programming
//cover_image: https://direct_url_to_image.jpg
---

Last year Shopify started developing the All-new POS application. There was a small problem, given that all screens are presented as full screen to the user we needed the ability to distinguish a modal screen vs the rest. iOS 13 had a great answer to this.

It feels like every new iOS version adds something to `UITraitCollection` or `UIUserActivity`. iOS 13 was no different. There was an handy small addition to `UITraitCollection` for apps with floating windows. That addition was [userInterfaceLevel]( https://developer.apple.com/documentation/uikit/uitraitcollection/3238085-userinterfacelevel).

## What is UserInterfaceLevel?
Apple describes it as the visual level for content in a window.  The possible values are `base`, `elevated`, and `unspecified`. The first one being the window’s main content and the last one anything above it. This will be the perfect match for our need of modal windows having a dedicated background colour.

## Using it to meet our requirement

```swift
import UIKit

public struct AdaptiveColor {
	/// See [UserInterfaceLevel](https://developer.apple.com/documentation/uikit/uiuserinterfacelevel) for more info.
	private(set) var base: (light: UIColor, dark: UIColor)
	/// The color used for content visually above your window's main content. If none is specified, the `base` color is used instead.
	///
	/// See [UserInterfaceLevel](https://developer.apple.com/documentation/uikit/uiuserinterfacelevel) for more info.
	private(set) var elevated: (light: UIColor, dark: UIColor)
	
	public init(light: UIColor, dark: UIColor) {
		base = (light: light, dark: dark)
		elevated = base
	}
	
	public init(base: (light: UIColor, dark: UIColor), elevated: (light: UIColor, dark: UIColor)) {
		self.base = base
		self.elevated = elevated
	}
	
	public var value: UIColor {
		if #available(iOSApplicationExtension 13.0, *) {
			return UIColor { traitCollection in
				let isElevated = traitCollection.userInterfaceLevel == .elevated
				if traitCollection.userInterfaceStyle == .dark {
					return isElevated ? self.elevated.dark : self.base.dark
				} else {
					return isElevated ? self.elevated.light : self.base.light
				}
			}
		} else {
			return base.light
		}
	}
}
```

The previous snippet is how Shopify’s [Point of Sale application](https://shopify.com/pos) is handling dynamic colours. You should focus on line #24, we detect the current elevation of the user interface and decide which of the two colour sets to use for this particular colour.

Now, let’s say we want to change the background colour of a view all we need to do is:

```swift
view.backgroundColor = AdaptiveColor(base: (light: .white, dark: .black), elevated: (light: .lightGray, dark: .gray)).value
```

And thanks to the excellent [UIAppearance]( https://developer.apple.com/documentation/uikit/uiappearance) we can style our `UINavigationController` similarly how we styled the background view, and all our screens will be displayed with the correct colour.

Putting everything together into a project, it looks something like this:

![Demo](https://dev-to-uploads.s3.amazonaws.com/i/tkyknud0l3rfcoop2vgu.gif)

## Further reading

That is all!, as always you can find the full source code on GitHub

{% github raulriera/technical-articles no-readme %}