Wednesday, June 4, 2025

SwiftUI macOS Sheet Buttons

Sam Rowlands:

Sheet dialog buttons don’t meet the macOS human interface guidelines by default, I’ve tried some solutions in the past, but then I stumbled across a really simple way to do it and I’m sharing that now.

[…]

Yes, it’s that simple, use a toolbar and the placement attributes to specify which buttons perform which action and SwiftUI will not only place the buttons correctly, but will resize the default and cancel buttons to match the Apple Human Interface Guidelines.

Except now the window shows a horizontal line for the toolbar. Still, this is the easiest way I’ve seen so far.

Previously:

5 Comments RSS · Twitter · Mastodon


That code doesn’t look fragile at all.

Wtf you can’t specify a min. width for a button in SwiftUI? Either raw point min.width value or % relative to parent?


It's still baffling to me that Apple ruined standard dialogs in macOS. It's bad enough that they opted for center aligned text and portrait orientation on a system that consistently uses landscape orientation, for no reason other than trying to make things look like iOS, as though that were important for some reason. Plus now the buttons are never in a predictable layout, so it's that much easier to click the wrong button. But they also don't work properly as designed.

At one point I saw a standard dialog box that had three buttons, one of which had no border, one of which looked normal, and one of which looked disabled. I had no idea which one would be triggered if I pressed return.


>Plus now the buttons are never in a predictable layout, so it's that much easier to click the wrong button.

I think there will be more unpredictability if SwiftUI continues to expand.

Seems to me that in SwiftUi your real layout code is an implementation detail controlled by Apple, not by you the developer. I have a big problem with this. This means that when they change the underlying implementation it can break your layout in unpredictable ways (this has already happened to plenty of developers).

It makes things so much worse that the default behavior results in terrible UI as shown in the blog post linked here as "how NOT TO DO IT."

Honestly the first bit of code doesn't look "wrong" in any obvious way (other than the fact that Apple's underlying implementation creates bad UI). But stick a "toolbar" in there and it looks better and I guess you're supposed to just know that? But will it stay that way? I don't want to play whack-a-mole with my layout code on every OS update. I'd rather assume responsibility for view's frames even if that is more "work" initially because when the developer owns the frame it isn't supposed to break on OS updates unless there is a really bad OS bug. If the real layout isn't part of the API contract Apple can always come back at you and say "you were just lucky that that layout worked to begin with, but you were really doing it wrong the entire time."


The more I hear people on this blog talk about their experiences with SwiftUI, the more it sounds like a disaster.


@ObjC4Life Yeah, the layouts shouldn’t be so fragile from version to version. One of problems in this example is that expressing equal widths is harder than with auto-layout. But also, why can’t it just do the right thing in such a basic case? It already knows that there are two buttons and one is Cancel and one is the default button. I thought the whole point is that the framework is supposed to know the platform-specific guidelines. Even from Mac OS X 10.0, dragging the OK and Cancel buttons from the palette in Interface Builder would make them the right size (though not when localized).

Leave a Comment