Greg Lloyd
Greg Lloyd boosted

I think I just figured out why I (and I think several other #iOS developers who have used #UIKit before) have developed somewhat of an animosity against #SwiftUI:

SwiftUI makes simple things really simple. It also makes some very specific complex things simple.

But despite the theoretically really high customizability (it’s all custom views with lots of modifiers overall), that‘s at first glance much higher than UIKit, getting things just right and creating a solution that feels just excellent is really hard. And by now I’m convinced that creating excellent solutions that really fit in well with the OS and offer a great, frictionless UX to people using your app is harder in SwiftUI.

However, creating a solution that works and is good enough is easier in SwiftUI. With it you fairly quickly arrive at a solution where it’s hard to argue that the small pieces of friction, the slight irregularities in the UI, the bits where people can accidentally „hold it wrong“, that these things should be removed.

I believe these bits of friction occur more often in SwiftUI and are harder to remove than in UIKit.

Add to that the higher initial cost of getting a working solution in UIKit at all and this strongly tips the balance in favor of „good enough“ UX when using SwiftUI, and away from excellent UX.

And I hate that about SwiftUI.

The more I think about it everything about #SwiftUI and around it feels like „good enough“ (admittedly in a fairly high level of „good enough“, but decidedly not excellent).

The View Debugger still doesn’t work with SwiftUI. Using colored backgrounds in code for debugging is good enough.

SwiftUI doesn’t have overview system documentation (how do I think about SwiftUI? what’s good architecture with SwiftUI? Etc.). Having (admitted mostly good and fairly complete) documentation for individual types is good enough.

In the official SwiftUI tutorials basically everything is about iOS. Only in the very last chapter a Mac app is added. It’s created as separate target, despite Xcode supporting unified targets for iOS and macOS for several years now, there just wasn’t time to update it. The Mac app also only has about half the functionality of the iOS app because it turns out about half the patterns used in the iOS app don’t actually work well on macOS. It’s good enough that we proved that some of that code can run on macOS, we don’t need feature parity or keep it up to date.

We updated the Earthquakes sample app to use SwiftUI (and SwiftData) from UIKit (and CoreData). Originally it displayed a whole month of earthquakes. But that was too slow when using the new frameworks. So we’ll just change the sample app to show only the last 24 hours of earthquakes. That‘s good enough to demonstrate the concepts.

SwiftUI contains a lot of symbols, which makes it symbols file really large. So we strip the symbols from the framework when shipping the OS despite this meaning all SwiftUI frames in the debugger, in crash reports (maybe except for the ones coming from Apple itself) and Instruments will be unsymbolicated. We do this to save a few megabytes of OS size on disk. Stripping the symbols and giving only unsymbolicated frames to developers is good enough. (Note: this was fixed in iOS 18 and aligned releases, but I’m still bitter about it.)

You cannot make two views in different hierarchies the same size. Containment-based layout is good enough.

The #SwiftUI View Body instrument only shows body executions despite a lot of work happening in other parts of the code. Leaf views like Text and container views like V/HStack also don’t have body getters so they also don’t show up. Having view bodies from your own named views show up + some SwiftUI views is good enough. (Note: the SwiftUI instrument in Instruments 26 was significantly improved. I believe it fixes some of these issues no have not formed an opinion on it, yet)

A SwiftUI Form view in the grouped style is embedded into its own scroll view. In the grouped style it’s not in a scroll view. There is no way to get rid of the scroll view around a grouped form to eg embed it in your own scroll view with additional UI. Having Form only work well if it’s filling the whole content of the current container is good enough.

Being able to completely disable interactive dismiss of sheets is good enough. There is no need to have a delegate callback (like in UIKit) that would allow putting up a confirmation dialog if data would be lost by „swipe to dismiss“. You can either turn it in or off, that’s it.

Applying a background modifier to a Grid does not actually set the background of the grid but only of all the individual grid elements. That’s good enough.

Our design Toolkits for Figma and Sketch still contain the default cell styles from UIKit (single label, title + subtitle label, label + value) but there isn’t actually any way to easily create these in SwiftUI. It’s good enough to have devs work with designers to figure out what the precise measurements, fonts etc. in Figma are to try to replicate what‘s sold to designers as a default component in SwiftUI.

Who needs a target-action-first-responder pattern in menus? Action closures should be good enough for everyone. It you really want to, you can just call NSApplication to invoke that responder chain manually from the closure.

#iOS #UIKit

I think I just figured out why I (and I think several other #iOS developers who have used #UIKit before) have developed somewhat of an animosity against #SwiftUI:

SwiftUI makes simple things really simple. It also makes some very specific complex things simple.

But despite the theoretically really high customizability (it’s all custom views with lots of modifiers overall), that‘s at first glance much higher than UIKit, getting things just right and creating a solution that feels just excellent is really hard. And by now I’m convinced that creating excellent solutions that really fit in well with the OS and offer a great, frictionless UX to people using your app is harder in SwiftUI.

However, creating a solution that works and is good enough is easier in SwiftUI. With it you fairly quickly arrive at a solution where it’s hard to argue that the small pieces of friction, the slight irregularities in the UI, the bits where people can accidentally „hold it wrong“, that these things should be removed.

I believe these bits of friction occur more often in SwiftUI and are harder to remove than in UIKit.

Add to that the higher initial cost of getting a working solution in UIKit at all and this strongly tips the balance in favor of „good enough“ UX when using SwiftUI, and away from excellent UX.

And I hate that about SwiftUI.