How to Recreate Control Events in SwiftUI

Mark van Wijnen
17 min readMar 20, 2024
Photo from Handling touches in your view

Background

At WWDC 2018, Apple designers presented a talk titled “Designing Fluid Interfaces”, explaining the design reasoning behind the gestural interface you see in your phone today. If you haven’t seen the talk yet, I highly suggest you do.

For this story we will focus on the Designing a tap part at around 01:04:40 into the video. Here they demonstrate some best practices for tapping a button by looking at the stock Calculator-app.

Apple Designing Fluid Interfaces

The key points they address are the following:

  1. The button should highlight immediately when it is touched.
  2. Do not confirm the touch until the touch goes up.
  3. Create an extra margin around the tap area.
    This makes the touch more comfortable and avoids accidental cancellation if a touch is moved during the interaction.
  4. The user should be able to change its mind when the button is touched.
    If the user drags their finger outside the tap area and lifts it, the tap should be cancelled. The same way, if the user drags their finger back inside the tap area, the button should highlight again and by lifting their finger they can confirm it.

Demo

With this in mind let’s roughly recreate the Calculator-app buttons with SwiftUI and see how they hold against those key points given in the talk.

struct CalculatorButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.system(size: 40))
.foregroundStyle(.white)
.frame(width: 70, height: 70)
.background(
Circle().fill(
configuration.isPressed ?
Color(red: 115/255, green: 115/255, blue: 115/255) :
Color(red: 51/255, green: 51/255, blue: 51/255)
)
)
}
}

As of writing, March 2024, ButtonStyle provides us with two properties that we can use to style the button:

  1. isPressed
    A Boolean that

--

--

Mark van Wijnen

macOS/iPadOS/iOS/watchOS/visionOS developer and SwiftUI enthousiast. “Stay Hungry, Stay Foolish!” — Steve Jobs