簡體   English   中英

SwiftUI - 確定電流設備和方向

[英]SwiftUI - Determining Current Device and Orientation

我試圖檢測設備何時在 iPad 和縱向上。

目前我在 UIKit 中使用UIDevice API 並使用環境 object 來觀察變化。 我使用此處找到的解決方案 - Determining Current Device and Orientation

然而, orientationInfo.orientation最初總是等於.portrait直到旋轉成縱向然后再回到橫向。

因此,當執行以下操作以顯示FABView

struct HomeView: View {

@EnvironmentObject var orientationInfo: OrientationInfo
let isPhone = UIDevice.current.userInterfaceIdiom == .phone

    var body: some View {
      ZStack(alignment: .bottom) {
          #if os(iOS)
          if isPhone == false && orientationInfo.orientation == .portrait {
            FABView()
          }
          #endif
      }
    }
}

當 iPad 最初處於橫向時,將加載視圖,但當更改為縱向並返回橫向時,將被刪除。 為什么會發生這種情況,如何確保在第一次加載時未加載視圖?

完整代碼

struct HomeTab: View {
    
    var body: some View {
        NavigationView {
            HomeView()
                .environmentObject(OrientationInfo())
        }
    }
}

struct HomeView: View {

@EnvironmentObject var orientationInfo: OrientationInfo
let isPhone = UIDevice.current.userInterfaceIdiom == .phone

    var body: some View {
      ZStack(alignment: .bottom) {
          #if os(iOS)
          if isPhone == false && orientationInfo.orientation == .portrait {
            FABView()
          }
          #endif
      }
    }
}

final class OrientationInfo: ObservableObject {
    enum Orientation {
        case portrait
        case landscape
    }
    
    @Published var orientation: Orientation
    
    private var _observer: NSObjectProtocol?
    
    init() {
        // fairly arbitrary starting value for 'flat' orientations
        if UIDevice.current.orientation.isLandscape {
            self.orientation = .landscape
        }
        else {
            self.orientation = .portrait
        }
        
        // unowned self because we unregister before self becomes invalid
        _observer = NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: nil) { [unowned self] note in
            guard let device = note.object as? UIDevice else {
                return
            }
            if device.orientation.isPortrait {
                self.orientation = .portrait
            }
            else if device.orientation.isLandscape {
                self.orientation = .landscape
            }
        }
    }
    
    deinit {
        if let observer = _observer {
            NotificationCenter.default.removeObserver(observer)
        }
    }
}

您可以使用UIDevice.orientationDidChangeNotification來檢測方向更改,但在應用啟動時不應依賴它。

UIDevice.current.orientation.isValidInterfaceOrientation將在開始時為假,因此兩者

  • UIDevice.current.orientation.isLandscape

  • UIDevice.current.orientation.isPortrait

將返回false

相反,您可以使用第一個 window 場景中的interfaceOrientation

struct ContentView: View {
    @State private var isPortrait = false
    
    var body: some View {
        Text("isPortrait: \(String(isPortrait))")
            .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
                guard let scene = UIApplication.shared.windows.first?.windowScene else { return }
                self.isPortrait = scene.interfaceOrientation.isPortrait
            }
    }
}

另請注意,設備方向不等於界面方向 當設備在縱向模式下倒置時,設備方向為縱向,但界面方向也可以為橫向

我認為在您的情況下最好依靠界面方向。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM