Tuesday, February 11, 2020

More About SwiftUI

Apple (via Tony Arnold):

You’ll start by adding a macOS target to your project, and then reusing the shared data you created for the iOS app. With all of the assets in place, you’ll create SwiftUI views to display list and detail views on macOS.

Follow the steps to build this project, or download the finished project to explore on your own.

Chris Eidhof:

After a few months spent delving into SwiftUI, we decided to write a short book: it’s called Thinking in SwiftUI. Since SwiftUI is still in its early days, the book focuses on the concepts behind the framework that we believe are essential to understand. It is not a reference for SwiftUI’s platform-specific APIs, but rather a guide to honing your intuition about how SwiftUI works.

Nikita Prokopov (Hacker News):

First, the general approach SwiftUI is taking (reactive declarative data-driven UI framework) is really solid and considered state-of-the-art as of the current day of the year. No complaints here, great job, we all needed that, thank you Apple for releasing it. No, seriously. It’s a great tool and I’m looking forward to using it.

But, a few things I noticed in SwiftUI concern me. I think they could illustrate points in the UI framework design that future systems could handle better. Without further ado, let’s start with the biggest problem in API design: commas!

Will Townsend:

Today I’ll explain how to create your own Button Styles, and hopefully show you the difference between ButtonStyle and PrimitiveButtonStyle, and why you’d use one or the others.

Scott James Remnant (via Joshua Emmons):

One of the first things presented about SwiftUI is that its views choose their own sizes, and that once chosen, those choices cannot be overridden. This is such a simple statement that it would be easy to move on quickly to get to the good stuff.

This would be a mistake, because this simple statement fundamentally changes everything you know about layout.

[…]

This doesn’t contradict what we’ve just learned about chosen sizes not being able to be overridden, it actually demonstrates another key principle we haven’t learned yet: a view receives a proposed size from its parent before it chooses its own size.

Alexander Grebenyuk:

SwiftUI no longer uses Auto Layout, gone all of the cruft introduced over the years. SwiftUI has a completely new layout system designed from the ground up to make it easy to write adaptive cross-platform apps. […] I can’t be more excited to dig deep into the SwiftUI layout system to see what it has to offer.

Ole Begemann:

SwiftUI’s layout algorithm may be simple on the surface, but the way the built-in views and view modifiers interact is tremendously complex (and largely undocumented).

Javier:

After spending some time testing the limits of alignment guides, I arrived at the conclusion that they do work. However, there’s confusion about what we expect from them. This confusion comes from not realizing there’s a whole set of implicit alignment guides in effect. When we ignore them, things do not go our way.

Javier:

In this short article, we are going to explore several aspects of View equality. We’ll see what happens when we make a view conform to Equatable, and what is the purpose of EquatableView and the .equatable() modifier.

Javier:

If you’ve been using SwiftUI for a while now, you probably hit the problem where you find yourself trying to update the state of a view from inside its body. Usually, Xcode complains during runtime. When it does, you are forced to put your update inside a DispatchQueue closure (not feeling too good about yourself) but you carry on anyway. Does this sound familiar? In this article, we’ll discuss why it sometimes is perfectly fine to apply that technique, but some other times, it’s a no-no (leading to CPU spikes or app crashes).

Jared Sorge:

In my last post I talked about some of the struggles I’m having getting up to speed with SwiftUI. Let’s dive in to a couple of examples.

Rob Whitaker:

Apple has taken the chance to re-think how some of their accessibility tools work for developers, and they’ve baked in accessibility right from the very beginning. Apple’s accessibility teams have been an integral part of some of the decisions that have shaped SwiftUI. You can see this throughout your SwiftUI code.

Mattt Thompson:

It’s hard to overstate how much of a game-changer Xcode Previews are for iOS development, and we couldn’t be happier to incorporate them into our workflow.

Kishikawa Katsumi:

I published SwiftUI online playground.

You can try SwiftUI and see the rendering results insanely easily.😊

Thomas:

I tried to replicate my app’s GUI using SwiftUI. Couldn’t get the basic layout right: standard controls do not size themselves correctly. Also, popup buttons do not draw their menu correctly. SwiftUI is plain broken on macOS.

I continue to hear about problems like this.

Wooji Juice:

If you want to make a Mac app, there are 4 primary APIs you could be using, in a sorta 2x2 grid: AppKit, UIKit (w/Catalyst), SwiftUI-in-AppKit, SwiftUI-in-UIKit. It’s a complex mess of what each does/doesn’t support — figuring out which to use for any given UI is trial & error

I’ve been trying to make one relatively simple bit of UI (in a standalone testbed app) for days. Every time I think I’m on a roll, I bump into a different wall of missing functionality. I try different implementations. I try different designs that don’t need same features.

It’s not even like you can say “Screw it, I’ll do everything old-school pure native AppKit and get access to everything”, cuz you’ll still be missing some things (e.g. SF Symbols aren’t supported, even tho they are all available on Mac since Catalyst apps can use them).

Previously:

24 Comments RSS · Twitter

"SwiftUI no longer uses Auto Layout"

So this would mean the Auto Layout history would look something like this:

AutoLayout 1.0: it's a revolution, you need to write the layout constraints with code in a syntax that is so good that developers created their own APIs and syntaxes.
AutoLayout 2.0: it's a revolution, you can edit the constraints in a UI that almost nobody understand and that usually produces errors that nobody understand either.
AutoLayout 3.0: it's a revolution, we're suggesting you to use the autoresizing flags whenever you can to avoid using constraints.
AutoLayout 4.0: It's a revolution, introducing new stacking and grid views so that you can enjoy how UI could be done with Java AWT (or is it X11? I don't remember).
AutoLayout 5.0: It's a revolution, it's gone.

I'm so sad I never used Auto Layout.

@stephane autolayout was a failure. It was obvious from the very beginning that that technology was not going to work. Some developers will open their mouths and swallow whatever Apple feeds. Swiftui will be no different. They should fix bugs and improve existing tools instead of reinventing the wheel every 5 years.

I don't really understand what problem a "reactive declarative data-driven UI framework" is actually fixing. I've discussed it with colleagues who use React for web development and they can't give me a straight answer. It feels like it's being driven by the usual software fad-ism that eschews understanding and expertise in favour of flitting to whatever the next framework du jour that promises them the moon on a stick.

As far as live previews in Xcode go, well, they've been a thing in Windows development for decades so I'm not particularly impressed.

I haven't used SwiftUI seriously yet, but I want to defend Auto Layout.

Auto Layout was a vast improvement over the old springs and struts system for certain situations. Its killer feature was handling UI localizations for different languages. Instead of manually hand-tweaking each UI multiple times, once for each translation, you just let your constraints adjust controls automatically as need. This is a Godsend over the old localization process!

Auto Layout is overkill for simple UIs, and had its crufty and frustrating parts (I especially dislike the "visual format" strings), but overall it is a nice system when you have more advanced layout needs.

Sören Nils Kuklau

> As far as live previews in Xcode go, well, they've been a thing in Windows development for decades so I'm not particularly impressed.

My understanding is the SwiftUI live previews _run_ the current view (without the rest of the app around it, but with the ability to provide sample values), which is fairly different from the WinForms or XAML UI designers in Windows development.

(And if it were similar to them, your criticism still wouldn't work, since if anything, the VB/WinForms UI designer is inspired by NeXT's Interface Builder, which Xcode's UI designer is a direct descendant of.)

Apple should be rightfully criticised for many things regarding development tools and processes these days, but I never understood whiners, who complain just about anything related to Apple (or any other entity, for that matter). Saying that auto layout was the failure and that the technology never worked from the very beginning can be done only by people who never actually used it. Probably for being too lazy to dedicate an hour or two to get into its concept. Because, that time was needed to understand auto layout concepts good enough to escape the realm of “springs and struts” (where our brains were captured for more than a decade) and start designing simple UIs in a much more logical way than “springs and struts” ever made it possible. And on top of it, be 100% sure the UI elements arrangement will stay consistent no matter how you resize surrounding views and windows.

For more (and very) complex UIs, auto layout removed a need for thousands (literarily) lines of boilerplate code and even that code very ofter couldn't guarantee your UI will stay consistent in every possible situation. Martin mentioned localisation, rightfully so; before auto layout, the only way to be completely sure your UI will be consistent and look right in all localisations was to create a copy of EVERY nib in your project for EVERY localisation you provide. Auto layout solved that with only ONE nib and NO additional code at all (perhaps sometimes in some extremely rare situations).

Auto layout was based on some mathematical principles and when it was first presented on WWDC in 2001 (I think), even the list of scientistic papers backing the technology was listed in the presentation (I'm lazy to dig it now). I cannot be sure, but it may be UI layout in SwiftUI is further development based on same mathematical principles, but involving less of developer's input. Whether that was good or bad idea, we are about to see.

Sören Nils Kuklau

>Auto layout was based on some mathematical principles and when it was first presented on WWDC in 2001 (I think)

Er.

I don't think Autolayout was introduced until 2012?

And while I wouldn't call it a "failure" as someone else did, it does seem kind of damning (and a bit Microsoft-esque) that, shortly after shipping it, they already started developing yet another incompatible layout system. It's missing the coherent single-path-forward story.

I don’t really understand the hate for Auto Layout. To me, the main issues are that some Cocoa controls were/are buggy with it, it’s not a great fit for Interface Builder, and sometimes there are performance issues. But the basic design was sound from the beginning, and it’s been incredibly useful. If anything, I worry that Swift UI is going to make the easy stuff a bit easier while losing some of the flexibility of Auto Layout.

Heartily sick of the Swift-ObjC impedance mismatch, I really want to give SwiftUI a chance. But every time I look at code examples I nauseate at the “Ruby Cleverness” of it all. Bad method names, stupid syntactic sugar, and structure and presentation logic all glommed into one big ball of mud. Honestly, it’s like HTML 2.0 before the amateurs responsible for that mess wised up and sort of moved appearances out of the markup and into separate CSS.

Trust a bunch of C++ fanbois to drag our future down to their hindbrain level of thought, and beat it to death with rocks.

--

“It’s a curious thing about our industry: not only do we not learn from our mistakes, but we also don’t learn from our successes.” – Keith Braithwaite

@Sören
> I don't think Autolayout was introduced until 2012?

I said I'm lazy to dig it and I don't quite remember, but wasn't it introduced during Lion's time?

@Michael
> I worry that Swift UI is going to make the easy stuff a bit easier while losing some of the flexibility of Auto Layout.

My worries exactly. That's why I said whether their decision for "less of developer's input is good or bad idea" is yet to be seen.

@Dragan Yes, Auto Layout was introduced with Lion in 2011.

@Michael, @Sören,

Yeah, only now I see it, that "2001" in the initial post was clearly a typo :-)

Michael: “[AutoLayout is] not a great fit for Interface Builder”

You’re being much too kind. My (few) GUIs are very basic so have had little need for AL, but when I have tried to use it it’s just been a pain. IB takes nice declarative concepts that could be cleanly and concisely explain an entire interface in a few lines of text, spreads that information over separate per-widget GUI configs mixed in with all the other IB crap, and makes it impossible to get an overview of how everything relates, or understand why it behaves the way it behaves when it doesn’t behave the way you want it to.

Cocoa Bindings is exactly the same: making Xcode’s UX a hundred times worse than it should be by using the wrong medium (GUI configs instead of text-based DSL) to express things. Plus, of course, when the bottom drops out of CB (which it often does), you’re left wracking your brains as you dig through endless IB screens trying to figure out what you’ve done wrong. Like I say, my GUIs are pretty basic; building them should not be this hard.

Unfortunately, while SwiftUI does now use text to express everything, the text that it uses (Swift code) is lousy for expressing such specialized concepts as presentation (CSS) and layout (algebra). Typical nuclear-powered jackhammer, treating everything as a nail even as it knocks them clean through the wall.

Swift’s C++ wonks may be great compiler engineers, but they’re lousy as language designers.

Gahh, that was me. Stupid HTML form. (As you can guess, I don’t like those either.)

Sören Nils Kuklau

@Dragan

>Yeah, only now I see it, that "2001" in the initial post was clearly a typo :-)

Ah, I see. That was my confusion. :) I suppose that's almost a decade at this point. Time flies.

@Dragon
>For more (and very) complex UIs, auto layout removed a need for thousands (literarily) lines of boilerplate code and even that code very ofter couldn't guarantee your UI will stay consistent in every possible situation. Martin mentioned localisation, rightfully so; before auto layout, the only way to be completely sure your UI will be consistent and look right in all localisations was to create a copy of EVERY nib in your project for EVERY localisation you provide. Auto layout solved that with only ONE nib and NO additional code at all (perhaps sometimes in some extremely rare situations).

Maybe saying Autolayout was a failure was harsh, but the times when I found auto layout useful is actually for more basic UI to avoid boilerplate code (easy spacing between views, equal with constraints, ect.). For *really* complex UI you'd often end up having to make 'size class' specific constraints, which IMO made seeing how everything fits together a lot more complicated. And if the size class groupings Apple defined didn't work for you, it can make placing something where you wanted even more complicated because you'd have to change constraints in code at runtime.

Stack views and stuff make making Preference windows a lot faster. But I'd prefer that they just let devs create a preference UI from a plist file (as is the case for iOS Settings bundles). Seems silly I have to create virtually the same spacing constraints between checkboxes for settings in every xib for every app that I create. Autolayout here doesn't get rid of the boilerplate, it just changes it. It would be nice if I could just make a Settings plist, which could be used to generate a settings view controller for both iOS and Mac.

When you design for a bunch of different form factors, there probably isn't ever going to be a "perfect" layout system for every situation. I just always thought autolayout was too complicated.

@Anonymous If you do auto layout in code, you can abstract away a lot of the boilerplate.

@Sören
> My understanding is the SwiftUI live previews _run_ the current view (without the rest of the app around it, but with the ability to provide sample values), which is fairly different from the WinForms or XAML UI designers in Windows development.

WinForms is relatively dumb but XAML UI designers are different. If the developer choses to they support a design mode via attached properties to populate the content with live data. Many choose not to but that's on them.

@Martin

"Auto Layout was a vast improvement over the old springs and struts system for certain situations. Its killer feature was handling UI localizations for different languages. Instead of manually hand-tweaking each UI multiple times, once for each translation, you just let your constraints adjust controls automatically as need. This is a Godsend over the old localization process!"

Frankly, certain situations are mostly centering vertically or horizontally.

The only case where Auto Layout would have been useful is to address the totally stupid issues introduced by Helvetica Neue and its incompatible metrics.

I always found the old localization process to be the fastest one. But this certainly requires to avoid massive view hierarchies in one's xibs.

@Michael "To me, the main issues are that some Cocoa controls were/are buggy with it, it’s not a great fit for Interface Builder, and sometimes there are performance issues."

Considering that Auto Layout is bad when it comes to NSTableView and it's very uncommon for me to have a project without at least a NSTableView, Auto Layout is the first thing I uncheck when I create a xib.

Also worth mentioning, the Outlet HUD inspector of Xcode does not behave as usual if Auto Layout is enabled.

I'm also wondering whether debugging auto layout rules written by someone else is not as painful as debugging KVO code written by someone else.

@stephane What’s the issue with NSTableView?

@Michael Performance issue. For instance with dynamic row heights. At least in the first OS X versions that supported AL. I haven't checked in a while.

Try making UWP apps for Windows. I'm reluctant to say this, but these days Microsoft is ages ahead of Apple if you compare their developer's ecosystems.
Apple's documentation is a sick joke. Microsoft's documentation is the best documentation I've ever read.
Swift UI is a joke. Swift UI preview in Xcode is a joke. Just compare it to XAML and XAML previewer in Visual Studio.
...and the list goes on an on...

@stephane
"I always found the old localization process to be the fastest one. But this certainly requires to avoid massive view hierarchies in one's xibs."

I can't imagine the old localization being the fastest, even for small projects with simple xibs. What’s fast about duplicating each and every xib for each and every language, and then adjusting them all by hand? It’s pure busy work. The modern localization process using Base.lproj is much cleaner: import text from your translator and have Auto Layout adjust your UIs. It’s entirely automated and there’s no data duplication; the translated text is factored out of the UI entirely, as it should be.

The old system was also a nightmare to maintain as an app changed. If you want to change anything (eg: a data source in a xib, add a new control, etc) you have to do it N times, once for each language in each xib, and hope you don’t make any mistakes (or test N times too). I prefer that my tools eliminate that kind of error-prone busy work.

@Martin

1. You absolutely do not need to duplicate each and every xib:

Numerous xibs are usually unlocalized. Either because there are no labels (e.g. pure layout views) or the text is dynamically defined by the code and there are absolutely no needs for autolayout or autoresizing rules to handle most of them.

2. If you trust Autolayout and never check all the languages you ship, you are overly optimistic:

The "busy"works lets you check that the localized UI are correct at the same time.

When you look at the localized flavor of the Apple system applications, you understand that Auto Layout adjust the UI without any guarantee that the UI will fit correctly its enclosing window or pane. For instance the French localization of the OS was getting better and better and for the last years, the quality went down when it comes to text layout.

3. Importing the text from the translator is fast, sure. As fast as importing them for the old localization process. The only issue with dealing with just .strings file is that the context of the string is missing. With the old localization process, the context is there. With Base.lproj, you had to wait until 2018 for the problem to be solved in theory (I haven't used the localization catalog yet).

4. Regarding app changes. I would rather extract a string from a xib and request a localization of it and then paste it back than having to figure out where this string is located in the .strings file. e.g. if you have multiple instances of the "New" string and need to modify only one them, how can you figure out in the .strings file which one is the good one quickly? Maybe there's a quick solution for this but it does not seem obvious.

Leave a Comment