SwiftUI adaptive Popover swipe-to-dismiss is broken

Development / iOS / Making of Captionista

While working on the iPad UI variant for our iPhone video subtitles app Captionista, I noticed that when swiping to dismiss in compact horizontal size class or on iPhone, the popover transition freaks out — as recently as iOS 14.1 and SwiftUI 2.

Workaround: Do the “adaptive” part of popover presentation on compact size classes yourself – if the horizontal size class is currently compact use sheet instead of popover. You could probably roll your own View modifier to achieve this more graciously, but here’s the low-tech solution to keep the example simple:


struct YourView: View {
@Environment(\.horizontalSizeClass) var sizeClass

var body: some View {
    VStack {
      if sizeClass == .compact {
          Button(action: { showSheet.toggle() }) {
             Text("Settings")
          }
          .sheet(isPresented: $showSheet) { 
              YourView()
        }
      } else {
          Button(action: { showPopover.toggle() }) {
             Text("Settings")
          }
          .popover(isPresented: $showPopover) { 
              YourView()
              .frame(width: 300, height: 500) // Set a size for Popovers
        }
      }
    }
  }
}

This one has a Feedback: FB8889254 “SwiftUI popovers do not transition correctly when swiping to dismiss on iPad or iPad (h-compact split view)”

The Author

Marc Palmer (Twitter, Mastodon) is a consultant and software engineer specialising in Apple platforms. He currently works on the iOS team of Concepts sketching app, as well as his own apps like video subtitle app Captionista. He created the Flint open source framework. He can also do a pretty good job of designing app products. Don't ask him to draw anything, because that's really embarrassing. You can find out more here.