SwiftUI デバイスのインターフェイスタイプでView(デザイン)を切り替える+方向でView(デザイン)を切り替える

前記事

SwiftUI デバイスのインターフェイスタイプでView(デザイン)を切り替える

メインでデバイスのインターフェイスタイプ判断、生成するViewを切り替える。
PhoneView側にiPhoneでのデザイン、PadView側にiPadでのデザインを書けば良い。
Viewをパーツ化しておけば、インターフェイスタイプ毎にデザインを調整できる。

追加

PadView側で方向判断、生成するViewを切り替える。

Example

ExampleDeviceApp.swift

import SwiftUI

@main
struct ExampleDeviceApp: App {
    var model: Model = Model()
    
    var body: some Scene {
        WindowGroup {
            if UIDevice.current.userInterfaceIdiom == .pad {
                PadView()
                    .environmentObject(self.model)
            }
            else {
                PhoneView()
                    .environmentObject(self.model)
            }
        }
    }
}

PadView.swift

import SwiftUI

struct PadView: View {
    @EnvironmentObject var model: Model

    var body: some View {
        if self.model.orientation == .portrait || self.model.orientation == .portraitUpsideDown {
            PadPortraitView()
        }
        else {
            PadLandscapeView()
        }
    }
}

struct PadView_Previews: PreviewProvider {
    static var previews: some View {
        PadView()
    }
}

PhoneView.swift

import SwiftUI

struct PhoneView: View {
    @EnvironmentObject var model: Model

    var body: some View {
        Text("iPhone")
            .font(.largeTitle)
    }
}

struct PhoneView_Previews: PreviewProvider {
    static var previews: some View {
        PhoneView()
    }
}

PadPortraitView.swift

import SwiftUI

struct PadPortraitView: View {
    var body: some View {
        Text("PadPortraitView")
            .font(.largeTitle)
    }
}

struct PadPortraitView_Previews: PreviewProvider {
    static var previews: some View {
        PadPortraitView()
    }
}

PadLandscapeView.swift

import SwiftUI

struct PadLandscapeView: View {
    var body: some View {
        Text("PadLandscapeView")
            .font(.largeTitle)
    }
}

struct PadLandscapeView_Previews: PreviewProvider {
    static var previews: some View {
        PadLandscapeView()
    }
}

Model.swift

import Foundation
import SwiftUI

final class Model: ObservableObject {
    @Published var orientation: UIDeviceOrientation = .portrait

    init() {
        let notificationCenter = NotificationCenter.default
        
        notificationCenter.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: nil, using: { notification in
            guard UIDevice.current.orientation != .faceUp && UIDevice.current.orientation != .faceDown && UIDevice.current.orientation != .unknown else {
                return
            }
            guard self.orientation != UIDevice.current.orientation else {
                return
            }
            print("Notification")
            print(UIDevice.current.orientation.description)
            self.orientation = UIDevice.current.orientation
        })

    }
}

Extensions.swift

import Foundation
import UIKit

extension UIDeviceOrientation: CustomStringConvertible {
    public var description: String {
        var result = ""
        switch self.rawValue {
        case 0:
            result = "unknown"
        case 1:
            result = "portrait"
        case 2:
            result = "portraitUpsideDown"
        case 3:
            result = "landscapeLeft"
        case 4:
            result = "landscapeRight"
        case 5:
            result = "faceUp"
        case 6:
            result = "faceDown "
        default:
            break
        }
        return result
    }
}

extension UIInterfaceOrientation: CustomStringConvertible {
    public var description: String {
        var result = ""
        switch self.rawValue {
        case 0:
            result = "unknown"
        case 1:
            result = "portrait"
        case 2:
            result = "portraitUpsideDown"
        case 3:
            result = "landscapeLeft"
        case 4:
            result = "landscapeRight"
        case 5:
            result = "faceUp"
        case 6:
            result = "faceDown "
        default:
            break
        }
        return result
    }
}

SwiftSwift,SwiftUI

Posted by shi-n