マルチプラットフォームアプリで、
Mac/iPad と iPhone/AppleTV でグループ分けしてそれなりに切り替える。
if prefersTabNavigation { // *
//if UIDevice.current.userInterfaceIdiom == .phone { // NG on macOS
//if UserInterface.prefersTabNavigation {
TabView(selection: $screen) {
ForEach(Screen.allCases) { screen in
screen.destination
.tag(screen as Screen?)
.tabItem { screen.label }
}
}
} else {
NavigationSplitView {
SidebarList(screen: $screen)
} detail: {
DetailColumn(screen: screen)
}
}
判定の条件 (Bool) をどう書くか。
🔀 Apple 公式サンプル
WWDC23 でアナウンスの新機能ですか。
👉 Unleash the UIKit trait system - WWDC23 - Videos - Apple Developer
便利な SwiftUI Environment に UIKit UITrait をブリッジするという UITraitBridgedEnvironmentKey を使った方法。
// Create custom Environment
struct PrefersTabNavigationEnvironmentKey: EnvironmentKey {
static var defaultValue: Bool = false
}
extension EnvironmentValues {
var prefersTabNavigation: Bool {
get { self[PrefersTabNavigationEnvironmentKey.self] }
set { self[PrefersTabNavigationEnvironmentKey.self] = newValue }
}
}
// Bridge UITrait read only
#if os(iOS)
extension PrefersTabNavigationEnvironmentKey: UITraitBridgedEnvironmentKey {
static func read(from traitCollection: UITraitCollection) -> Bool {
return traitCollection.userInterfaceIdiom == .phone || traitCollection.userInterfaceIdiom == .tv
}
static func write(to mutableTraits: inout UIMutableTraits, value: Bool) {
// Do not write
}
}
#endif
@Environment(\.prefersTabNavigation) private var prefersTabNavigation
高級な感じで相互読み書き可能な状態にできるのはいいけども。
🔀 その他
なんとなく試しながら書いてみました。
Constants な感じで。書き方はいくつかあるようです。
enum を使う。意見はいろいろありそう。
enum UserInterface { // as namespace
static var prefersTabNavigation: Bool {
#if os(iOS) //canImport(UIKit)
let idiom = UIDevice.current.userInterfaceIdiom
return idiom == .phone || idiom == .tv
#else
return false
#endif
}
}
フツーに struct で書く。
struct UserInterface {
static var prefersTabNavigation: Bool {
#if os(iOS) //canImport(UIKit)
let idiom = UIDevice.current.userInterfaceIdiom
return idiom == .phone || idiom == .tv
#else
return false
#endif
}
}
👉 `static let` in enum vs struct? - Using Swift - Swift Forums
呼び出し側。
if UserInterface.prefersTabNavigation {
🔀 まとめ
#if os(iOS)
ての、なんとなく
なるべくは使いたくないです。
Apple 公式サンプルは、新機能を強引に Read Only でサンプルコードに利用した感じに見えるけどもー。
【SwiftUI】iOS と macOS で互換したいコードの一つの解法
👉 https://t.co/gUgv9B40x7#プログラミング #SwiftUI— chanzmao (@maochanz) May 23, 2024