在Apple Watch和iPhone上使用SwiftUI进行设备特定的布局

时间:2019-07-04 21:10:57

标签: ios apple-watch swiftui watch-os

有时候,我需要对设备进行特定于布局的调整。例如,我可能需要减小屏幕较小的iPhone上的间距,或者增大屏幕较大的iPhone上的间距。使用UIKit(甚至是Interface Builder),可以很容易地为特定尺寸的类设置布局例外。 使用SwiftUI进行条件特定于设备的布局的最佳方法是什么?

我一直在搜索SwiftUI文档,还没有找到在布局中访问和使用此类信息的方法。

以下是Apple Watch应用的示例。根据Apple的设计指南,我在40mm Series 4的左侧和右侧添加了8.5个填充点。但是,44mm应具有9.5个填充点,并且任何比Series 4早的Apple Watch都不应填充。 >

使用SwiftUI实现此目标的最佳方法是什么?

struct ContentView : View {

    var body: some View {
        HStack {
            Text("Hello World")
        }.padding([.horizontal], 8.5)
    }
}

3 个答案:

答案 0 :(得分:3)

通常,您可以使用两种方法来实现设备特定的布局:

  1. 通过@Environment变量确定类的大小
  2. GeometryReader用于更细粒度的控制

不幸的是,UserInterfaceSizeClass仅具有.compact.regular,并且在watchOS上不可用。

要使用环境:

struct MyView: View {
    @Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
}

要使用GeometryReader:

var body -> some View {
    GeometryReader { proxy in
      if proxy.size.width > 324.0 { // 40mm watch resolution
        MyBigView()
      } else {
        MySmallView()
      }
    }
}

作为参考,以下是手表的分辨率:

  • 40mm:394×324
  • 44毫米:448×368
  • 38毫米:340×272
  • 42毫米:390×312

答案 1 :(得分:0)

对于iPhone,我可以使用以下环境:

@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?

然后在var body中:一些View我这样做是为了处理图像如何根据屏幕尺寸缩放。在iPad和iPhone X及更高版本上进行了大量测试。我敢肯定还有其他方法。这至少是在SwiftUI中使用大小类的一种方式。关于如何使用尺寸类的信息还很少。

Image("logo")
      .opacity(1.0)
      .scaleEffect(makeCircleTextBig ? (horizontalSizeClass == .compact ? 0.18 : 0.25) : (horizontalSizeClass == .compact ? 0.06 : 0.1))
      .animation(.easeIn(duration: 1.0))

还可以查看ControlSize: Apple Docs ControlSize

并通过其他方法检查一下: Hacking With Swift: SwiftUI size classes

答案 2 :(得分:0)

@gohnjanotis,不确定是否为时已晚,但是您是否尝试在GeometryReader前面添加返回值?当我使用某些条件时,我经常会收到该错误,在实际创建视图之前先让let等。因此,它应如下所示:

var body: some View {
        return GeometryReader { proxy in
          if proxy.size.width > 324.0/2.0 { // 40mm watch resolution in points
            Text("BIG view here")
          } else {
            Text("small view here")
          }
        }
    }