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

Ios 在Apple Watch和iPhone上使用SwiftUI的设备特定布局,ios,apple-watch,swiftui,watchos,Ios,Apple Watch,Swiftui,Watchos,有时,我需要对布局进行特定于设备的调整。例如,我可能需要缩小屏幕较小的iPhone上的间距,或者增加最大屏幕上的间距。使用UIKit(甚至界面生成器),可以很容易地为特定大小的类创建布局异常使用SwiftUI进行条件设备特定布局的最佳方法是什么? 我一直在浏览SwiftUI文档,但还没有找到在布局中访问和使用此类信息的方法 下面是一个Apple Watch应用程序的示例。根据苹果的设计指南,我在40mm系列4的左右两侧添加了8.5个填充点。然而,44毫米应该有9.5个填充点,任何比系列4旧的苹果

有时,我需要对布局进行特定于设备的调整。例如,我可能需要缩小屏幕较小的iPhone上的间距,或者增加最大屏幕上的间距。使用UIKit(甚至界面生成器),可以很容易地为特定大小的类创建布局异常使用SwiftUI进行条件设备特定布局的最佳方法是什么?

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

下面是一个Apple Watch应用程序的示例。根据苹果的设计指南,我在40mm系列4的左右两侧添加了8.5个填充点。然而,44毫米应该有9.5个填充点,任何比系列4旧的苹果手表都应该没有填充

使用SwiftUI实现这一目标的最佳方法是什么

struct ContentView : View {

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

通常,有两种方法可用于实现特定于设备的布局:

  • 通过
    @Environment
    变量调整类大小
  • 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/2.0 { // 40mm watch resolution in points
            MyBigView()
          } else {
            MySmallView()
          }
        }
    }
    
    以下是手表的分辨率,仅供参考:

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

    除以2.0以获得它们在
    点中的值,而不是iPhone中的
    像素值,我可以这样使用环境:

    @Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
    
    然后在VarBody中:我做了一些视图来处理图像如何根据屏幕大小进行缩放。在iPad、iPhoneX和更大的手机上做了一系列测试。我相信还有其他方法。这至少是在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:

    并查看以下不同的方法:
    @gohnjanotis,不确定是否为时已晚,但您是否尝试在GeometryReader前面添加一个返回?在实际创建视图之前,当我使用某些条件时,我经常会遇到这种错误。因此,它应该如下所示:

    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")
              }
            }
        }
    

    当我以GeometryReader的方式尝试它时,我得到一条错误消息,上面说
    编译器无法在合理的时间内对这个表达式进行类型检查;尝试将表达式分解为不同的子表达式
    ,但我无法生成它。(Xcode 11.0 beta 3)关于如何克服这个问题,或者仅仅是一个Xcode错误,有什么想法吗?对于使用
    GeometryReader
    的有效代码,我遇到了很多编译器错误。一种解决方法是将内容放在一个函数中,比如
    func mySizedContent(proxy:GeometryProxy)->一些视图{…}
    ;在
    GeometryReader
    闭包的开头添加显式类型以消除歧义,但我不确定我对Swift和Swift UI的理解是否足够,以确定需要指定什么才能使其编译。对答案的小更正:分辨率为@2x。代理返回1x处的值。所以它应该类似于proxy.size.width>324/2