robb
@robb.is
SwiftUI and iOS shenanigans @ Linear.app • I put the UI in Ennui • today your love, tomorrow the world • previously: SwiftUI, Google Research, UIKit.
https://robb.is
https://robb.is
Today, we've updated Linear Mobile with an all-new design that looks great on iOS 26, and thanks to the powerful APIs #SwiftUI has been adding over the past few years, we're bringing it to iOS 18 with zero compromise.
Get the update here: apps.apple.com/app/linear-m...
Get the update here: apps.apple.com/app/linear-m...
October 16, 2025 at 5:04 PM
Today, we've updated Linear Mobile with an all-new design that looks great on iOS 26, and thanks to the powerful APIs #SwiftUI has been adding over the past few years, we're bringing it to iOS 18 with zero compromise.
Get the update here: apps.apple.com/app/linear-m...
Get the update here: apps.apple.com/app/linear-m...
I'm working on a post on how to implement the iCloud Sign In animation in #SwiftUI – coming soon to patreon.com/swiftui_snippets
June 29, 2025 at 8:23 PM
I'm working on a post on how to implement the iCloud Sign In animation in #SwiftUI – coming soon to patreon.com/swiftui_snippets
Hell froze over, I made a macOS app! github.com/robb/FolderI... Use it to generate custom folder icons that match the ones found on macOS Sequoia.
June 1, 2025 at 7:28 PM
Hell froze over, I made a macOS app! github.com/robb/FolderI... Use it to generate custom folder icons that match the ones found on macOS Sequoia.
When animating a count in #SwiftUI, use `monospacedDigits()` so the frame doesn’t change as frequently – however, that can leave leading 1s look disconnected so I'm skipping it for the first digit while keeping formatting intact gist.github.com/robb/f8fdcca...
April 17, 2025 at 5:08 PM
When animating a count in #SwiftUI, use `monospacedDigits()` so the frame doesn’t change as frequently – however, that can leave leading 1s look disconnected so I'm skipping it for the first digit while keeping formatting intact gist.github.com/robb/f8fdcca...
I've published a new #SwiftUI Package to automatically visualize touches during Screen Recording, Screen Mirroring and when using the iOS Simulator: github.com/robb/visuali...
March 3, 2025 at 7:43 PM
I've published a new #SwiftUI Package to automatically visualize touches during Screen Recording, Screen Mirroring and when using the iOS Simulator: github.com/robb/visuali...
You’ll find the value is only dependent on the radius, so you can just multiply with the radius instead of creating a whole Path and taking it apart.
(unless of of course, it crosses the midpoint of the shortest edge)
(unless of of course, it crosses the midpoint of the shortest edge)
March 2, 2025 at 9:07 PM
You’ll find the value is only dependent on the radius, so you can just multiply with the radius instead of creating a whole Path and taking it apart.
(unless of of course, it crosses the midpoint of the shortest edge)
(unless of of course, it crosses the midpoint of the shortest edge)
If you create a 9-slice from a rounded rectangle you created on iOS, you need to take into account that the distance from the corner to the first axis-aligned control point is about 152.866% of the radius.
I found this value through some empirical computer science in a quick #SwiftUI preview.
I found this value through some empirical computer science in a quick #SwiftUI preview.
March 2, 2025 at 8:38 PM
If you create a 9-slice from a rounded rectangle you created on iOS, you need to take into account that the distance from the corner to the first axis-aligned control point is about 152.866% of the radius.
I found this value through some empirical computer science in a quick #SwiftUI preview.
I found this value through some empirical computer science in a quick #SwiftUI preview.
Using #SwiftUI’s UIGestureRecognizerRepresentable and Anchor Preferences, you can build a ButtonStyle that is triggered by a long-press in a parent view in addition to regular taps.
This enables building custom menus like this that allow triggering an action with a single long press.
This enables building custom menus like this that allow triggering an action with a single long press.
January 19, 2025 at 9:46 PM
Using #SwiftUI’s UIGestureRecognizerRepresentable and Anchor Preferences, you can build a ButtonStyle that is triggered by a long-press in a parent view in addition to regular taps.
This enables building custom menus like this that allow triggering an action with a single long press.
This enables building custom menus like this that allow triggering an action with a single long press.
Work-in-Progress #SwiftUI glitch effect featuring chroma subsampling; random offsets for lines, blocks and pixels; chromatic abberation in YCbCr as well as RGB channel shuffling.
January 1, 2025 at 8:40 PM
Work-in-Progress #SwiftUI glitch effect featuring chroma subsampling; random offsets for lines, blocks and pixels; chromatic abberation in YCbCr as well as RGB channel shuffling.
The SVG effect on display here is a group of feGaussianBlur ➝ feColorMatrix ➝ feOffset filters grouped in a feMerge. That translates 1:1 to GraphicsContext.Filter.blur, .colorMatrix and . projectionTransform drawn on top of each other.
December 8, 2024 at 1:03 PM
The SVG effect on display here is a group of feGaussianBlur ➝ feColorMatrix ➝ feOffset filters grouped in a feMerge. That translates 1:1 to GraphicsContext.Filter.blur, .colorMatrix and . projectionTransform drawn on top of each other.
Pro Tip: you can, like "Right-click, View Source" on the web and port your favorite SVG effects to SwiftUI as their graphics primitives are very similar.
December 7, 2024 at 6:08 PM
Pro Tip: you can, like "Right-click, View Source" on the web and port your favorite SVG effects to SwiftUI as their graphics primitives are very similar.
Quick tutorial how the stitching was achieved:
- Use `strokedPath(_:)` to split the path into multiple lines, using a two-component dash array.
- Convert to a CGPath, split it into subcomponents using `componentsSeparated(using:)`.
- Apply a rotation to each line.
- Merge them back together.
- Use `strokedPath(_:)` to split the path into multiple lines, using a two-component dash array.
- Convert to a CGPath, split it into subcomponents using `componentsSeparated(using:)`.
- Apply a rotation to each line.
- Merge them back together.
December 5, 2024 at 11:27 PM
Quick tutorial how the stitching was achieved:
- Use `strokedPath(_:)` to split the path into multiple lines, using a two-component dash array.
- Convert to a CGPath, split it into subcomponents using `componentsSeparated(using:)`.
- Apply a rotation to each line.
- Merge them back together.
- Use `strokedPath(_:)` to split the path into multiple lines, using a two-component dash array.
- Convert to a CGPath, split it into subcomponents using `componentsSeparated(using:)`.
- Apply a rotation to each line.
- Merge them back together.