1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftUIにおけるViewの縦横判定

Posted at

一般的にcompact/regularで判断付けていた気がするけれど。

前提

widthをw、heightをhと表す。
compactをC、regularをRと表す。

compact/regularのまとめ

iPhoneが縦向きの場合、全てwChRである。
iPhoneの横向きの場合、全てhCである。

iPadはフルスクリーン時において、縦向き横向き、全てwRhRである。
iPadが縦向きでsplit viewを使う場合、全てwChRである。
iPadは2/3 split viewの場合、横向きは全てwRhRである。
それ以外のsplit viewは全てwChRである。

したがって、iPadの場合「縦か横か」を判定するためにSizeClassが使えない(レイアウトの振り分けには使えるけれど)

Notificationを使う

単純な縦横を知りたいだけならば次のモディファイアを足す。

.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { output in
            guard let device = output.object as? UIDevice else { return }
            // device.orientation.isPortrait のtrue / falseで判断つく
        }

検証用ソース

struct ContentView: View {
    
    var iPhoneLandscape : some View {
        Text("iPhone Landscape")
    }
    
    var iPhonePortrait : some View {
        Text("iPhone Portrait")
    }
    
    var iPadLandscape : some View {
        Text("iPad Landscape")
    }
    
    var iPadPortrait : some View {
        Text("iPad Portrait")
    }
    
    var main: some View {
        VStack {
            switch deviceSize {
            case .wChR:
                Text("wChR")
            case .wRhR:
                Text("wRhR")
            case .wChC:
                Text("wChC")
            case .wRhC:
                Text("wRhC")
            }
            
            switch device {
            case .pad:
                if isPortrait {
                    iPadPortrait
                } else {
                    iPadLandscape
                }
            case .phone:
                if isPortrait {
                    iPhonePortrait
                } else {
                    iPhoneLandscape
                }
                // 他の端末は何もしない
            case .unspecified, .tv, .carPlay, .mac:
                EmptyView()
            @unknown default:
                EmptyView()
            }
        }
    }
    
    enum DeviceSize {
        case wRhR
        case wRhC
        case wChR
        case wChC
    }
    
    // iPadかiPhoneか
    let device = UIDevice.current.userInterfaceIdiom
    // 横向きか縦向きか
    @State private var isPortrait: Bool = UIDevice.current.orientation.isPortrait
    
    // compact/regular
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    @Environment(\.verticalSizeClass) private var verticalSizeClass
    
    var deviceSize: DeviceSize {
        guard let horizontalSizeClass , let verticalSizeClass else {
            return .wRhR
        }
        switch (horizontalSizeClass, verticalSizeClass) {
        case (.regular, .regular):
            return .wRhR
        case (.regular, .compact):
            return .wRhC
        case (.compact, .regular):
            return .wChR
        case (.compact, .compact):
            return .wChC
        default:
            return .wRhR
        }
    }
    
    
    var body: some View {
        main
        .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { output in
            guard let device = output.object as? UIDevice else { return }
            self.isPortrait = device.orientation.isPortrait
        }
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?