Kuba Suder's blog on Mac & iOS development

SwiftUI On All Devices

Categories: SwiftUI, WWDC 19 0 comments Watch the video

SwiftUI is the shortest path to building great apps on every device

SwiftUI is designed to accomodate many UI paradigms – it can be used with a mouse, touch, digital crown, remote, or assistive technologies

It has great support for any specific platform’s conventions out of the box

It was built with the help of experts from all devices, to make sure that on each platform it feels right at home

Learn once and use anywhere

Common elements that render in an appropriate way on every device

Common layout system that works the same way everywhere

More advanced elements like Picker

There’s no such thing as a “one size fits all app” – if you stick to the common denominator across all devices, you’ll be missing out on the things that make each device great, so you have to decide what the right design is for your app on each device

But you can share skills and tools and some code *where it makes sense*

When porting an app to a new platform, take a design-first approach: don’t just look at how to make the code run on the other platform, think about what is the right expression for your app on this device


Biggest, boldest screen

Often used together with friends

Used with Siri Remote, entire interface must be navigable using focus

Streamlined navigation

Rich, immersive experience – media, photos, videos, not performing tasks

Carefully consider which experiences make sense when viewed on a large screen

Here, we want to use: beautiful photos of landmarks, adding favorites, basic tourism information

We don’t want: lengthy historical information, advanced sorting & filtering, anything location-based

.focusable(canBecomeFocused) { isFocused … }  ⭢  set if element should be focusable and react to focus

.onPlayPauseCommand { }

.onExitCommand { }

Don’t use long, vertically scrolled and nested lists of text, use a navigation UI that emphasizes content (pictures)

Take advantage of the big screen

On iOS, when using both a navigation controller and tab controller, the tab controller is the top level and a navigation controller may be used in one or more tabs, so that when you navigate deeper the tab bar is still visible

On tvOS, the tab controller should be added *inside* navigation controller, so that you see tabs at the top on the root level, but when you select some content, the tabs disappear


High information density – a large screen with relatively small fonts, so you can show a lot of information

Higher tolerance for large amounts of text

Precision pointing device allows smaller click targets and denser controls (within reason!)

Multiple window support

Keyboard shortcuts

Touch Bar

SwiftUI automatically adjusts padding/spacing to be appropriate for the Mac

Use .controlSize() for more compact controls

Menu item commands:

extension Command {
  static let showExplore = Command(Selector((“showExplore:”)))

view.onCommand(.showExplore) { self.selectedTab = .explore }

Touch Bar:

view.touchBar(TouchBar {
  Button(action: show) { Image(…) }
  Button(action: delete) { Text(…) }

To reuse the same container view between platforms but customize e.g. the row type class, you can parametrize the container with the row type and add a rowProvider:

struct SharedLandmarksList<LandmarkRowType: View>: View {
  var rowProvider: (Landmark) -> LandmarkRowType

struct MacLandmarksList: View {
  var body: some View {
    SharedLandmarksList() { landmark in
      return MacLandmarkRow(landmark: landmark)

double click  ⭢  tapAction(count: 2) { … }


A good rule is to aim for important actions to be reachable with 3 taps or less

.digitalCrownRotation modifier

.listStyle(.carousel) – a scrolling list that focuses on each cell