Indeed, but I prefer SwiftUI's syntax though, and the property wrappers + view modifiers paradigm, as well as Apple's Combine framework for processing data/events. Appears to result in less verbose and much cleaner, modular code compared to Dart+Flutter.
Yeah I really liked Flutter so I was excited that some of it's best ideas were coming to Apple. But Flutter is so young it's hard to imagine they rewrote whatever they had in a few months and got it ready to ship in just a few months for all of their major platforms. So I don't think they've borrowed it from Flutter, but if they did it might be even more impressive.
The first commit to Flutter was made in Oct 23 2014 (Initial name was Sky), It is almost as old as the Swift language itself. So, IMO, Swift UI had quite a bit inspiration from Flutter. If you look at the samples, the similarity is uncanny.
React Native uses methods 1 and 2. They have unified components that can be used across platforms, but they lack features, so most complex apps use the second approach. The big wins are a more known language (JS) and sharing a bunch of the "backend of the frontend".
The big downside happens when you add more systems (eg, web, OSX, Windows, Linux, etc). When you do this, the intersection shrinks and the potential for bugs in the shared widget increase dramatically.
Flutter uses methods 3 and 4. Rather than using the native widgets, they carry along Skia to do the rendering for them. This neatly skips most of the UI intersection issues because if the native widget for X lacks a certain feature, you can add it yourself in your custom widget. When dramatically different looks are desired, you can still use separate widgets for different systems. Adding additional systems is usually less difficult because rather than writing hooks into everything on the system, you only need more basic system hooks and the effort to get the renderer working.
The big downside here is development time and little inconsistencies. Instead of leveraging the work already done by the native developers (who probably know their system much better than the library's devs), everything must be built from scratch. Getting 90% there is easy, but getting every little detail working so it feels native is much harder. In addition, you must keep up with native widget changes which generally adds a lag time between their release and your catchup (but on the plus side, you may have already implemented some features they were missing). It should also be added that some UI features may not be available on some platforms (despite the shared widget) simply because the underlying OS does not support them, so multiple components may still be necessary for some things.
Both approaches have been tried in the past. Qt is probably the most successful at cross-platform design and they use the 3rd and 4th methods. I'm inclined to think its a better solution in the end even if it is more costly.
As a typical Mac snob, I used to care a lot about using native widgets. But UIKit doesn't even ship with a good-looking button class, and native apps often rewrite UI elements because the builtins are not very flexible (hello UITabBar). In theory that should make it easier for toolkits like Flutter to gain ground.
> But UIKit doesn't even ship with a good-looking button class
There are so few times when one should want to use a plain button in iOS anyway. Most times when a user needs to make a choice or start a task, they pick it from a UITableView, UIAlertController presented as an action sheet, or press a UINavigationItem.
> often rewrite UI elements because the builtins are not very flexible (hello UITabBar)
What's specifically missing here? You have items, each has an icon and text, they can also have badges. Tapping on items changes the currently shown content view. What's a tab bar supposed to do besides that?
A lot of the times I see these sorts of basic UI paradigms recreated, or the typical iOS HIG ignored by recreating an Android-style UI, the app can sometimes break when iOS has a major (or even minor) update or ignore accessibility guidelines. They're usually not significantly different in function, usually just aesthetics, and not usually sufficiently so to justify the cost.
> There are so few times when one should want to use a plain button in iOS anyway.
Almost every first-party app starts with a "Data & Privacy"/"What's New" dialog that uses a blue pill button, and almost every third-party app has a big fat "log in" button. Or look at Apple's redesigned Maps app. I don't know if I've ever worked on an app that didn't have its own ad-hoc button class.
> What's a tab bar supposed to do besides that?
Facebook, Instagram, Tweetbot etc. seem to have their own implementations because they want to hide the labels. Spotify has one to animate the icons when tapped. Audible has one to show the album art in the middle item. I'm going through my third-party apps right now, and only WhatsApp seems to use UITabBar as it was intended.
> the app can sometimes break when iOS has a major (or even minor) update
I nudge my clients towards stock UIKit components as much as possible, for all the reasons you mentioned, but I don't think UIKit is that much better than e.g. Flutter in the way that AppKit is many times better than Electron.
> Facebook, Instagram, Tweetbot etc. seem to have their own implementations because they want to hide the labels
All one has to do, to hide the labels, is set the labels to "" and adjust the image insets to account for the empty space.
> Audible has one to show the album art in the middle item
That's possible with stock UITabBar. Just set the appropriate image for the UITabBarItem and, again, adjust the image insets.
> and only WhatsApp seems to use UITabBar as it was intended
That's surprising. I don't use WhatsApp anymore, but most of it seemed custom. Well, that scores WA one point, I guess.
> I don't think UIKit is that much better than e.g. Flutter in the way that AppKit is many times better than Electron
Until you want to use iOS' built-in accessibility features, and you are disappointed to see that third party apps needlessly reimplemented widgets and didn't do the extra work to make them accessible.
Sadly, accessibility is always seen as an optional extra, not a fundamental feature. It's been a fundamental feature of AppKit and UIKit since time immemorial.
When some of these apps make it to macOS via Project Catalyst, this issue might become exacerbated to some extent.
You can hide the labels in a stock UITabBar, but you can't change its size, and I suspect this is what motivated Facebook and others to hide the labels in the first place.
You are right about the Audible use case, it might actually be using using a stock UITabBar. And in my experience WhatsApp has always been a pretty good platform citizen. It's one the very few icons on my home screen that tries to match Apple's style.
Agreed about a11y, I'm glad that Apple keeps bringing it up as a core feature.