SwiftUI

Getting started with Mesh Gradients on iOS 18

Published on: September 25, 2024

With iOS 18, we have the possibility to create mesh gradients. Mesh gradients are a really nice way to create very cool UI effects. In this post, we're going to explore exactly what mesh gradients are, how we can use them, and how we can even animate them to look really cool. We’ll start off looking at how we can create a mesh gradient. We're going to take a look at how it more or less works, and then we'll also look at what we can animate and how we can play with mesh gradients. At the end of the...

Read more...

Animating SF Symbols on iOS 18

Published on: September 4, 2024

Over the years, Apple has been putting tons of work into the SF Symbols catalog. With SF Symbols, we’re able to leverage built-in iconography that will look familiar to users while also fitting into the Apple ecosystem very nicely. The fact that there’s thousands of symbols to choose from makes it a highly flexible and powerful catalog of icons that, in my opinion, should be every designer and developer’s first choice when they’re looking for visual components to add to their apps. Initially, SF Symbols were pretty much static. We could configure them with a color and thickness but that...

Read more...

Adding values to the SwiftUI environment with Xcode 16’s Entry macro

Published on: July 15, 2024

Adding custom values to SwiftUI’s environment has never been very hard to do to. However, the syntax for doing it is verbose and easy to forget. To refresh your mind, take a look at this post where I explain how to add your own environment values to a SwiftUI view. To summarize what’s shown in that post; here’s how you add a custom value to the environment using Xcode 15 and earlier: private struct DateFormatterKey: EnvironmentKey { static let defaultValue: DateFormatter = { let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.dateFormat = "MM/dd/yyyy" return formatter }() } extension EnvironmentValues...

Read more...

Using PreviewModifier to build a previewing environment

Published on: July 10, 2024

Xcode 16 and iOS 18 come with a feature that allows us to build elaborate preview environments using a new PreviewModifier protocol. This protocol allows us to define objects that can create a single context or environment that’s cached and used across your SwiftUI previews. This is useful because it means that you could, for example, populate a database with a bunch of mock data that is then used in your previews. You can also use PreviewModifier to apply specific styling to your previews, to wrap them all in a specific wrapper, and more. Essentially, they’re a tool that allows...

Read more...

Mixing colors in SwiftUI and Xcode 16

Published on: June 18, 2024

SwiftUI in iOS 18 and macOS 15 has gained a new trick; it can mix colors. This means that it’s now possible to take a color and modify it by applying another color to it using a provided percentage. The video below shows how this works: Notice how the large rectangle updates its color to be a certain mix of a left and right color. In the video I use distinct colors but you can also mix with white or black to lighten or darken your color. One use of color mixing I like a lot is to explore color...

Read more...

Using iOS 18’s new TabView with a sidebar

Published on: June 12, 2024

In iOS 18, Apple has revamped the way that tab bars look. They used to be positioned at the bottom of the screen with an icon and a text underneath. Starting with iOS 18, tab bars will no longer be displayed in that manner. Instead, on iPad you will have your tab bar on the top of the screen with text-only items while on iPhone your tab bar will retain its old look. In addition to changing how a tab bar looks, Apple has also added new behavior to the tab bar; it can expand into a sidebar that contains...

Read more...

Building a stretchy header view with SwiftUI on iOS 18

Published on: June 11, 2024

In iOS 18, SwiftUI's ScrollView has gotten lots of love. We have several new features for ScrollView that give tons of control to us as developers. One of my favorite interactions with scroll views is when I can drag on a list an a header image animates along with it. In UIKit we'd implement a UIScrollViewDelegate and read the content offset on scroll. In SwiftUI we could achieve the stretchy header effect with GeometryReader but that's never felt like a nice solution. In iOS 18, it's possible to achieve a stretchy header with little to no workarounds by using the...

Read more...

Programmatic navigation in SwiftUI with NavigationPath and navigationDestination

Published on: May 22, 2024

One of the key features that was missing from SwiftUI when it first shipped was a good way to do programmatic navigation. There were some ways to handle this before iOS 16 introduced NavigationPath but it wasn’t very satisfying to use those APIs and they could be rather unreliable at times. To see an example, take a look at this post I wrote about handling deeplinks on iOS 14. In this post, I’d like to revisit programmatic navigation through iOS 16’s NavigationPath API which is a huge leap forward in terms of developer experience and reliability at the same time....

Read more...

Turn off sidebar hiding on NavigationSplitView in SwiftUI

Published on: May 21, 2024

By default, a NavigationSplitView in SwiftUI will show users an option to toggle the visibility of the sidebar. If you want to prevent this button from showing up so that users will always have to see your sidebar, you can do this by applying the toolbar(removing:) view modifier to your split view's sidebar as follows: NavigationSplitView(sidebar: { ExercisesList() .toolbar(removing: .sidebarToggle) }, detail: { ExerciseDetail(exercise: exercises.first!) }) The downside of doing this is that the button is hidden both in portrait and landscape modes. The result is that landscape users can no longer access your app's sidebar. To fix this you...

Read more...

Getting started with @Observable in SwiftUI

Published on: February 6, 2024

With iOS 17, we’ve gained a new way to provide observable data to our SwiftUI views. Until iOS 17, we’d use either an ObservableObject with @StateObject, @ObservedObject, or @EnvironmentObject whenever we had a reference type that we wanted to observe in one of our SwiftUI views. For lots of apps this worked absolutely fine, but these objects have a dependency on the Combine framework (which in my opinion isn’t a big deal), and they made it really hard for developers to limit which properties a view would observe. In iOS 17, we gained the new @Observable macro. I wrote about...

Read more...