首页 > 解决方案 > 组合框架的基本使用

问题描述

斯威夫特 5.2 iOS 14

尝试理解 SwiftUI 中的组合框架,并使用我在网上找到的示例将这段代码放在一起。但是……这个例子并不完整。

现在,当我更改设备的方向时,它确实会写入方向,但是如何在我的主循环中使用它呢?我似乎也找不到任何要订阅的内容,所以我尝试只使用 onChange。可悲的是,这不起作用。

class SizeClassViewV: ObservableObject {
  @Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
  @Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?

  enum Orientation {
    case portrait
    case landscape
  }
  @Published var orientation: Orientation = .portrait
  private var listener: AnyCancellable?

  init() {
    if horizontalSizeClass == .compact && verticalSizeClass == .regular {
      orientation = .portrait
    } else if horizontalSizeClass == .regular && verticalSizeClass == .compact {
      orientation = .landscape
    }
    listener = NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)
        .compactMap { ($0.object as? UIDevice)?.orientation }
        .compactMap { deviceOrientation -> Orientation? in
            if deviceOrientation.isPortrait {
                return .portrait
            } else if deviceOrientation.isLandscape {
                return .landscape
            } else {
                return nil
            }
        }
        .assign(to: \.orientation, on: self)
  }

  deinit {
    listener?.cancel()
  }
}

在我的主循环中现在看起来像这样?

struct ContentView: View {
@State var orient = SizeClassViewX()
var body: some View {
  Text("foo")
    .onChange(of: orient.orientation) { ( _ ) in
      print("changed")
    }
  }
}

更改方向时从不打印更改?

标签: iosswiftswiftuicombine

解决方案


我似乎找不到要订阅的内容

如果你看一下onReceive声明,你会发现它接受了一个 Combine Publisher

@inlinable public func onReceive<P>(_ publisher: P, perform action: @escaping (P.Output) -> Void) -> some View where P : Publisher, P.Failure == Never

这意味着如果您想以合并orientation方式订阅更改,您只需使用并传递相关的:onReceivePublisher

struct ContentView: View {
    @State var orient = SizeClassViewV()
    var body: some View {
        Text("foo")
            .onReceive(orient.$orientation) { _ in
                print("changed")
            }
    }
}

推荐阅读