📱

【UIKit/SwiftUI】Xcode 16 + iPadOS 18以降で、表示するシートのサイズが変わっている問題と対応

2025/02/10に公開

動作確認環境

Xcode 15.4
% /Applications/Xcode_15.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -version
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx15.0
Xcode 16.2
% /Applications/Xcode_16.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -version
swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)
Target: arm64-apple-macosx15.0

結論

下記コードのようにpresentationの形式を.pageSheet .pageに指定する

UIKit
let vc = SecondViewController()
vc.modalPresentationStyle = .pageSheet
present(vc, animated: true)
SwiftUI
.sheet(isPresented: $isPresented, content: {
    ContentSecondView()
        .presentationSizing(.page) // iPadOS 18以降のみ
})

経緯

Xcode 16系でbuildしたアプリは、iPadOS 18以降だとTabBarの表現が大きく変わったことは話題としてよく見かけると思うが、一方で他にもiPadOS 18未満と18以降で見た目が変わった箇所がある

下記のように、Xcode 16.2 + iPadOS 18系の組み合わせでは、UIKit(.present)、SwiftUI(.sheet)問わず、表示されるシートサイズが小さくなっている。

TabBarと違い、こちらはAppleのどういう判断で、シートサイズが小さいのがデフォルトになるようになったかはわからないが、意図しないサイズで表示されることで、デザイン崩れやファーストビューの量が減ることが予想されるため、少なくとも下限OSがiPadOS 18以上になるまでは、iPadOS 18未満の挙動に合わせることになる人が多いと思う。

Xcode 15.4

iPadOS 17.5 UIKit iPadOS 17.5 SwiftUI iPadOS 18.2 UIKIt iPadOS 18.2 SwiftUI

Xcode 16.2

iPadOS 17.5 UIKit iPadOS 17.5 SwiftUI iPadOS 18.2 UIKIt iPadOS 18.2 SwiftUI

検証コード(UIKit)

Xcode 16.2でUIViewControllerに対してlldbでpoコマンドを叩いた際、下記結果が得られる。

UIKit (iPadOS 17.5)
(lldb) po vc.modalPresentationStyle.rawValue
1
UIKit (iPadOS 18.2)
(lldb) po vc.modalPresentationStyle.rawValue
2

ここで、modalPresentationStyleの型のUIModalPresentationStyleを見てみると

UIModalPresentationStyle
public enum UIModalPresentationStyle : Int, @unchecked Sendable {

    case fullScreen = 0

    @available(iOS 3.2, *)
    case pageSheet = 1

    @available(iOS 3.2, *)
    case formSheet = 2

    @available(iOS 3.2, *)
    case currentContext = 3
...

とあるように、iPadOS 18以降では、何故か.formSheetがデフォルト値になっている。
そのため、以前のデフォルト値である.pageSheetを適用してあげれば、挙動が変わらない状態になる。

検証コード(SwiftUI)

UIKitみたくmodalPresentationStyleのようなpropertyを持っているわけではないようなので、直接表示されているサイズを調べる形で調査を行った。

その結果、UIKitと同様にiPadOS 18以降では、何故か.presentationSizing(.form)のサイズで表示されることがデフォルトになっていたため、.presentationSizing(.page)を適用することで、挙動を変えなくすることができる。

SwiftUIでもpoコマンド等で何か値を見て判断できる方法があれば、有識者の方に教えていただければ幸いです。

参考記事

  • なし

Discussion