Scaled Metric 在 Apple Watch 上不起作用?

Posted

技术标签:

【中文标题】Scaled Metric 在 Apple Watch 上不起作用?【英文标题】:Scaled Metric not working on Apple Watch? 【发布时间】:2021-01-10 23:22:27 【问题描述】:

我正在尝试针对 Apple Watch 执行此操作:

    @ScaledMetric var widthScale: CGFloat = 1

然后将 widthScale 应用到一些 SwiftUI View 元素的框架上:

    .frame(width: myFrame.width * widthScale, height: myHeight)

只是它根本没有改变。字体大小确实会发生变化,但 widthScale 始终保持 @ 1.0。

我理解错了吗?我发现错误了吗?它不应该在 WatchOS 上使用吗?

【问题讨论】:

似乎将 1 作为一个因素并不是一个好主意。使用 sizeCategory "extraExtraExtraLarge" 1 缩放到 1、10 缩放到 11.0 和 100 缩放到 112。所以我认为他们在内部使用 Int Scale 而没有公开事实。 【参考方案1】:

所以我通过反复试验发现了什么:

    @ScaledMetric 应该在它所应用的视图中定义,而不是在其他地方的结构类型中。 @ScaledMetric 值四舍五入到整个像素。因此,根据显示密度 x2 或 x3,它会四舍五入为 1/2halfs 或 1/3rds。 使用此视图和预览来查看不同的比例:
import SwiftUI

struct ScaledMetricText: View 
    @ScaledMetric(relativeTo: .caption) var widthScaleHundred: CGFloat = 100.0
    @ScaledMetric(relativeTo: .caption) var widthScaleTen: CGFloat = 10.0
    @ScaledMetric(relativeTo: .caption) var widthScaleOne: CGFloat = 1.0
    var body: some View 
        VStack 
            Text("Unscaled")
                .fixedSize(horizontal: true, vertical: false)
                .frame(width: 100)
                .background(Color(.lightGray))
                .padding(3)
            Text("100 -> \(widthScaleHundred)")
                .fixedSize(horizontal: true, vertical: false)
                .frame(width: 100 * widthScaleHundred / 100)
                .background(Color(.lightGray))
            Text("10 -> \(widthScaleTen)")
                .fixedSize(horizontal: true, vertical: false)
                .frame(width: 100 * widthScaleTen / 10)
                .background(Color(.lightGray))
                .padding(3)
            Text("1 -> \(widthScaleOne)")
                .fixedSize(horizontal: true, vertical: false)
                .frame(width: 100 * widthScaleOne)
                .background(Color(.lightGray))
        
        .font(.caption)
    


struct ScaledMetricText_Previews: PreviewProvider 
    static var previews: some View 
        ScaledMetricText()
            .previewDevice(PreviewDevice(rawValue: "Apple Watch Series 6 - 40mm"))
            .environment(\.sizeCategory, ContentSizeCategory.small)
        ScaledMetricText()
            .previewDevice(PreviewDevice(rawValue: "Apple Watch Series 3 - 38mm"))
            .environment(\.sizeCategory, ContentSizeCategory.extraExtraExtraLarge)
        ScaledMetricText()
            .previewDevice(PreviewDevice(rawValue: "Apple Watch Series 6 - 44mm"))
            .environment(\.sizeCategory, ContentSizeCategory.small)
        ScaledMetricText()
            .previewDevice(PreviewDevice(rawValue: "Apple Watch Series 3 - 42mm"))
            .environment(\.sizeCategory, ContentSizeCategory.extraExtraExtraLarge)

    

ios 预览:

struct ScaledMetricText_Previews: PreviewProvider 
    static var previews: some View 
        ScaledMetricText()
            .previewDevice(PreviewDevice(rawValue: "iPhone 8"))
            .environment(\.sizeCategory, ContentSizeCategory.small)
        ScaledMetricText()
            .previewDevice(PreviewDevice(rawValue: "iPhone 8"))
            .environment(\.sizeCategory, ContentSizeCategory.extraExtraExtraLarge)
        ScaledMetricText()
            .previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro Max"))
            .environment(\.sizeCategory, ContentSizeCategory.small)
        ScaledMetricText()
            .previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro Max"))
            .environment(\.sizeCategory, ContentSizeCategory.extraExtraExtraLarge)
    

【讨论】:

【参考方案2】:

通过下面的代码发现它确实有效。原则上,在模拟器和我的手表上。还是得搞清楚为什么上面的问题不行。

struct TextLabelsView: View 
    var body: some View 
        ScrollView(.vertical) 
            DynamicResizingView()
        
    


struct DynamicResizingView: View 
    @ScaledMetric(relativeTo: .largeTitle) var scaledLargeTitle: CGFloat = 10
    @ScaledMetric(relativeTo: .title) var scaledTitle: CGFloat = 10
    @ScaledMetric(relativeTo: .headline) var scaledHeadline: CGFloat = 10
    @ScaledMetric(relativeTo: .subheadline) var scaledSubheadline: CGFloat = 10
    @ScaledMetric(relativeTo: .body) var scaledBody: CGFloat = 10
    @ScaledMetric(relativeTo: .callout) var scaledCallout: CGFloat = 10
    @ScaledMetric(relativeTo: .caption) var scaledCaption: CGFloat = 10
    @ScaledMetric(relativeTo: .footnote) var scaledFootnote: CGFloat = 10
    @ScaledMetric() var scaledNothing: CGFloat = 10

    var body: some View 
        VStack(alignment: .leading) 
            Text("Dynamic Base10").font(Font.system(size:10))
            ScaledText(label: "LargeTitle", size: scaledLargeTitle)
            ScaledText(label: "Title", size: scaledTitle)
            ScaledText(label: "Headline", size: scaledHeadline)
            ScaledText(label: "Subheadline", size: scaledSubheadline)
            ScaledText(label: "Body", size: scaledBody)
            ScaledText(label: "Callout", size: scaledCallout)
            ScaledText(label: "Caption", size: scaledCaption)
            ScaledText(label: "Footnote", size: scaledFootnote)
            ScaledText(label: "Not Specified", size: scaledNothing)
        
    


struct ScaledText: View 
    var label: String
    var size: CGFloat
    var body: some View 
        Text("Scaled by \(label) to \(size, specifier: "%.2f")")
            .font(Font.system(size: size))
    


struct TextLabelsView_Previews: PreviewProvider 
    static var previews: some View 
        TextLabelsView()
            .environment(\.sizeCategory, ContentSizeCategory.accessibilityExtraExtraExtraLarge)
        TextLabelsView()
            .environment(\.sizeCategory, ContentSizeCategory.small)
    

通过这个,您可以看到不同 Font.TextStyle|s 的不同比例因子。

【讨论】:

以上是关于Scaled Metric 在 Apple Watch 上不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

Apple Watch Series 2 中的 CoreBluetooth

如何从 Apple Watch 中的手表扩展发送短信

为啥当我使用 QImage::scaled() 时我的内存消耗很大?

如果 iPhone App 处于非活动状态,是不是可以响应通过 Apple Watch 传输的文件?

万字长文解析Scaled YOLOv4模型(YOLO变体模型)

SAFe(Scaled Agile Framework)学习笔记