TIL

SwiftUI

You can find the official documentation here.

Also see Fucking SwiftUI (or Gosh Darn SwiftUI) for a nice “cheat sheet” and a breakdown of UIKit equivalent APIs.

WWDC Lounges

Example Apps

Apps built fully (or mostly) with SwiftUI.

Tutorials

Tools + Tips

A Companion for SwiftUI

An app that documents all the SwiftUI views, shapes, protocols, scenes, property wrappers, styles and environment values found in all platforms (iOS, macOS, tvOS, watchOS).

DetailsPro

A GUI for SwiftUI Design.

How to Find Why a SwiftUI View Is Updating

SwiftUI has a new, pretty cool, debugging utility to help you understand what is causing a view to be reevaluated.

Call Self._printChanges() inside the body of a view to print out the changes that have triggered the view update.

SwiftUI performance tips

SwiftUI has been around for almost 3 years now, and during this period working with it, I’ve noticed few groups of developer mistakes (both mine and from others) that can impact its performance. In this post, we will look at these pitfalls, and their potential solutions.

Working With UIViewRepresentable

When we work with SwiftUI, we can always drop down to UIKit level by using UIViewRepresentable, NSViewRepresentable or UIViewControllerRepresentable. The documentation around these protocols is still pretty sparse, and it can be hard to get them to work exactly the way we want. I tried to come up with some rules and patterns for using them.

Collections

API Changes

Known Issues + Workarounds

Dismissing the keyboard

Unfortunately, .keyboardDismissMode is not available in SwiftUI, so hacks are required:

Why Conditional View Modifiers are a Bad Idea

There are many blog posts out there with similar modifiers. I think all these blog posts should come with a huge warning sign. Why is the above code problematic? Let’s look at a sample.

SwiftUI seems to be breaking across OS releases on all platforms

See Michael Tsai’s post on iOS 15 Shortcuts and SwiftUI.

SwiftUI metrics & padding changes in macOS 12 are… ‘a problem’. I’m seeing all kinds of wrong behavior across my apps, compared to macOS 11. Fixing for one will break the other, which would mean a lot of nasty if statements. I hear iOS 15 has similar issues.

@stroughtonsmith

Growing increasingly concerned about this critical SwiftUI Button bug that breaks trackpad/click focus on iPadOS 15 + macOS Monterey. […] Oh wow, this bug is actually present in the Shortcuts app too (created in SwiftUI w/ iOS 15?)

@michael_tigas

We’re in ‘year 3’ of SwiftUI, and my base advice remains unchanged — it is great for auxiliary non-critical UI layouts (inspector sidebars, settings windows, and panels), watchOS apps, and rapid prototyping. Beyond that, it just does not meet the bar for complex, reliable apps

@stroughtonsmith

Retrospectives + Lessons Learned

Debugging

SwiftUI-Introspect library

Introspect underlying UIKit components from SwiftUI

Building SwiftUI debugging utilities

When working on any kind of app or system, it’s almost guaranteed that we’ll need to debug our code at one point or another. For example in order to reproduce a bug that’s been reported to us by either a tester or a user, to track down a race condition or some other source of ambiguity within our logic, or to fix a view that’s not being rendered correctly.

Inspecting SwiftUI views

But what if we wanted to know more about that view? In this article, let’s explore how we can do so.

Random Color for SwiftUI

Setting a random background color is a great way to detect an accidental SwiftUI loop. The tricky part is understanding what triggers the loop tho.

@steipete, Peter Steinberger

See also, David Smiths’s “Random Border Trick”:

A little trick I found super useful was to set the border of each of the various views involved to a random color and then it see what borders change whenever the view rebuilds. This helped me countless times to determine where in the view tree the problem was.

Behind the scenes: How SwiftUI works

clipped() doesn’t affect hit testing

The clipped() modifier in SwiftUI clips a view to its bounds, hiding any out-of-bounds content. But note that clipping doesn’t affect hit testing; the clipped view can still receive taps/clicks outside the visible area.

How an Hstack Lays out Its Children

For the most part SwiftUI’s layout system is intuitive to use, letting you achieve what you want with a little bit of experimentation. However, sometimes you encounter behaviors that are hard to reason about without a deeper understanding of the underlying implementation.

SwiftUI’s Grid Views

A few days ago we tweeted a series of layout quizzes for SwiftUI’s LazyVGrid to highlight some of the less obvious behaviors. In this post we’ll take a look at all three quiz questions and explain why the grid lays out its contents in the way it does.

Interestingly, we were not the only ones struggling to understand the behavior of grids: none of the most popular quiz answers were correct!

SwiftUI View Lifecycle

Each view undergoes a series of events from its birth to its death, which is referred to as a lifecycle. Understanding it is essential when building apps in SwiftUI. In this article, we will explore the three phases of the SwiftUI view lifecycle.

The Ultimate Guide to the SwiftUI 2 Application Life Cycle

For the longest time, iOS developers have used AppDelegates as the main entry point for their applications. With the launch of SwiftUI2 at WWDC 2020, Apple has introduced a new application life cycle that (almost) completely does away with AppDelegate, making way for a DSL-like approach.

In this article, I will discuss why this change was introduced, and how you can make use of the new life cycle in new or existing apps.

SwiftUI List Bindings: Behind the Scenes

As of WWDC 2021, SwiftUI supports bindings for list elements.

[…]

But how does it work?

SwiftUI: Understanding identity via transitions

In SwiftUI, identity holds the key to understanding how the rendering system works. A View’s identity tells SwiftUI which of that View’s values correspond to the same rendered view over time. This identity has strong implications for correctness, performance, and as we will see, transitions.

How the SwiftUI View Lifecycle and Identity Work

A beginner friendly article on view identity with an intro about Swift UI in general.

Working with Core Data

Core Data and SwiftUI

This is a large part of why I suggest creating an abstraction layer for Core Data. An abstraction layer allows me to hide the nitty gritty details of data mutation and persistence from the parts of the app that deal with displaying that data in the UI.

An initial approach might suggest that creating a Core Data abstraction layer requires foregoing all the nice affordances we have for quickly and expressively extracting information from the persistent store. Not so! The setup we’ll be going over allows me to have the abstraction layer while still using cool things (like property wrappers) for retrieving data.

Fetching objects from Core Data in a SwiftUI project

When you’ve added Core Data to your SwiftUI project and you have some data stored in your database, the next hurdle is to somehow fetch that data from your Core Data store and present it to the user.

Quick guide to using Core Data with SwiftUI

The easiest way to see how Core Data works with SwiftUI is by creating a new SwiftUI project and selecting the Use Core Data checkmark. Xcode will generate a working example that we can try out and review immediately.

Configuring SwiftUI Fetch Requests

In iOS 15, it’s easier to dynamically configure a Core Data fetch request for use with SwiftUI.

Project Setup

Setting up a multi-platform SwiftUI project

This blog will take a look at a basic setup for a multi-platform SwiftUI app.

How SwiftUI can now be used to build entire iOS apps

This year, however, entire apps can now be defined directly using SwiftUI, thanks to a few new additions to its API.

Layout

Impossible Grids with SwiftUI

Native support for grids in SwiftUI is finally here. This is made possible by two new views. These are LazyVGrid and LazyHGrid.

Sharing layout information in SwiftUI

SwiftUI views layout depends on each view state. This state is composed of a mix of internal properties, external values coming from the environment, etc.

Adaptive SwiftUI views

While this is great and can save us hundreds of hours, sometimes we want to make our UI declarations even more adaptive: in this article, let’s see how we can do so.

SwiftUI View That Fits

The SwiftUI ViewThatFits view, introduced in iOS 16, makes it a lot simpler to build layouts that adapt to make best use of the available space.

General “How To”

How to define SwiftUI properties

Here’s a first draft of a decision tree for how to define your SwiftUI properties…

A guide to SwiftUI’s state management system

What separates SwiftUI from Apple’s previous UI frameworks isn’t just how views and other UI components are defined, but also how view-level state is managed throughout an app that uses it.

[…]

This week, let’s take a closer look at each of those property wrappers, how they relate to each other, and how they make up different parts of SwiftUI’s overall state management system.

Mastering toolbars in SwiftUI

This week we will learn all about the new Toolbar API.

MatchedGeometryEffect | The SwiftUI Lab

We are talking about a new extension to the View protocol, the .matchedGeometryEffect() modifier. On its own, it’s good enough, but in combination with other techniques we learned already (custom transitions and animatable modifiers), it becomes even better. It is an essential skill to put in your SwiftUI toolkit.

Generating automatic placeholders for SwiftUI views

SwiftUI now ships with a new, built-in modifier that makes it really easy to automatically generate a placeholder for any view.

Creating custom .redacted effects

With the recent release of Xcode 12 we’ve gained a new .redacted(reason:) SwiftUI modifier.

Label

In this article, let’s explore this view beyond the basics.

NSUserActivity with SwiftUI

And now that SwiftUI also supports user activities and the scene delegates are gone, there’s even more change. A good time then, for a new article.

How to show and hide content with DisclosureGroup using SwiftUI

Now with the new SwiftUI capabilities, we can collapse content with DisclosureGroup. Let’s see how we could use it in various ways.

Mastering transitions in SwiftUI

In this article, we will go through all important parts related to the implementation of transitions in SwiftUI - from the very basics to more advanced techniques.

Encapsulating SwiftUI view styles

However, if we start exploring SwiftUI’s various APIs and conventions a bit further, it turns out that there are a number of tools and techniques that we can use to create a clean separation between our view hierarchy, its styles, and the components that we’re looking to reuse across a given project.

Handling loading states within SwiftUI views

One of the most important aspects of that kind of asynchronous work, at least when it comes to building UI-based apps, is figuring out how to reliably update our various views according to the current state of the background operations that we’ll perform. So this week, let’s take a look at a few different options on how to do just that when building views using SwiftUI.

Attributed Strings with SwiftUI

Before we begin, let’s put it right there: SwiftUI is not prepared to handle attributed strings easily. With that out of the way, let’s see the best approaches to fill that void and the limitations or problems we will find along the way.

Keyboard shortcuts in SwiftUI

This week, we will discuss the new keyboardShortcut modifier, which allows us to assign a shortcut to any interacting view.

Focus management in SwiftUI

One of these new APIs was the focus management API that we can use on iOS, macOS, tvOS, and watchOS. This week we will talk about SwiftUI functionality that allows us to manage the focus in our apps.

Avoiding SwiftUI’s AnyView

So, in this article, let’s take a look at two core techniques that can help us avoid AnyView while still enabling us to work with multiple view types in very dynamic ways.

Which SwiftUI property wrapper to choose in any situation

SwiftUI uses property wrappers to understand how we create and store data in our views, but if you need helping choosing which property wrapper is right for you I’ve made a tool to help. To find the right property wrapper for you, answer the questions below.

Nested Observable Objects in SwiftUI

At first blush, this looks fine – the view displays, and property within the nested view is shown as you’d expect; so what’s the problem? The issue is when you update that nested element’s property, even though it’s listed as @Published, the change doesn’t propagate to the view.

SwiftUI Custom Environment Values

Here’s my quick guide to creating your own custom SwiftUI environment values for things like global app settings.

Mastering SwiftUI previews

SwiftUI previews allow you to look at your SwiftUI views inside Xcode without running the app in the simulator. You can also preview UIKit views and controllers by wrapping them in SwiftUI. Today we will learn about all the powerful features of previews in Xcode.

The @ScaledMetric Property Wrapper

How can you scale other metrics, like spacing, as the dynamic type content size changes? In iOS 14, SwiftUI gained the @ScaledMetric property wrapper that can scale any numeric value.

Implementing Three Column Navigation in SwiftUI

In UIKit and AppKit, a UISplitViewController and a NSSplitViewController would be the necessary classes for building that functionality. In SwiftUI things are different though; a NavigationView with a couple of List views do the job in a much simpler fashion. The only requirement is to follow certain steps in the proper order.

Every SwiftUI Environment Value explained

…in this article, let’s review all environment values that SwiftUI offers.

How to add a clear button to a TextField

The TextField element of the SwiftUI framework does not have such a feature built-in, so you’d have to build your own solution for that. In this article I want to show how to accomplish a simple clear button inside a SwiftUI TextField element.

How to render text with a color gradient in SwiftUI

This article will explore how to render text with color gradients.

Running Code Only Once in SwiftUI

I’ve had a few situations in SwiftUI where I only want things to fire once and initially. At face value, this seems like a job for either .onAppear or the more nascent .task.