如何检索应用程序中的小部件大小以根据设备进行预览?

How to retrieve widget sizes in app to make a preview of it depending on the device?

我目前正在制作一个基于 SwiftUI 的仅小部件应用程序,它允许用户显示某些类型的信息,如时间、日期等。 为了使我的应用程序正常运行,我想在应用程序视图中预览小部件,同时允许用户进行设置。

目前一切正常,我可以 select 我的应用程序中的一个小部件并对其进行设置,以便小部件也进行更新。 但是,我遇到了一个问题,经过一些研究,我似乎找不到一种方法可以让您根据您使用的设备获取小部件的大小。

我尝试使用 UIScreen.main.bounds.size,但小部件尺寸和设备尺寸之间的宽高比不一样。

我想做的是让我的小部件预览适应设备实际使用的小部件大小。 (换句话说,根据您使用的设备检索小部件大小)

是否有任何解决方案可以动态地执行此操作,或者我是否需要为每个设备创建一个视图?提前致谢。

您可以将 UIScreen.main.bounds.size 映射到 Apple 文档中的小部件尺寸: https://developer.apple.com/design/human-interface-guidelines/widgets/overview/design/

小部件示例:

switch UIScreen.main.bounds.size {
    case CGSize(width: 428, height: 926):   return 170
    case CGSize(width: 414, height: 896):   return 169
    case CGSize(width: 414, height: 736):   return 159
    case CGSize(width: 390, height: 844):   return 158
    case CGSize(width: 375, height: 812):   return 155
    case CGSize(width: 375, height: 667):   return 148
    case CGSize(width: 360, height: 780):   return 155
    case CGSize(width: 320, height: 568):   return 141
    default:                                return 155
    }

您可以使用 displaySizeTimelineProviderContext 来获取当前 Widget 的大小。

func getTimeline(in context: Context, completion: @escaping (Timeline<Item>) -> Void) {
    print(context.displaySize)
    ...
}

您可以在您的 Widget Provider 中找到它。

如果需要,我添加了更多尺寸。

要获取家庭价值,您可以使用:@SwiftUI.Environment(\.widgetFamily) var family 从您的视图中

    func widgetHeight(forFamily family:WidgetFamily) -> CGSize {
    // better to use getTimeline func context.displaySize before this one.
    
    switch family {
    case .systemSmall:
        switch UIScreen.main.bounds.size {
        case CGSize(width: 428, height: 926):   return CGSize(width:170, height: 170)
        case CGSize(width: 414, height: 896):   return CGSize(width:169, height: 169)
        case CGSize(width: 414, height: 736):   return CGSize(width:159, height: 159)
        case CGSize(width: 390, height: 844):   return CGSize(width:158, height: 158)
        case CGSize(width: 375, height: 812):   return CGSize(width:155, height: 155)
        case CGSize(width: 375, height: 667):   return CGSize(width:148, height: 148)
        case CGSize(width: 360, height: 780):   return CGSize(width:155, height: 155)
        case CGSize(width: 320, height: 568):   return CGSize(width:141, height: 141)
        default:                                return CGSize(width:155, height: 155)
        }
    case .systemMedium:
        switch UIScreen.main.bounds.size {
        case CGSize(width: 428, height: 926):   return CGSize(width:364, height: 170)
        case CGSize(width: 414, height: 896):   return CGSize(width:360, height: 169)
        case CGSize(width: 414, height: 736):   return CGSize(width:348, height: 159)
        case CGSize(width: 390, height: 844):   return CGSize(width:338, height: 158)
        case CGSize(width: 375, height: 812):   return CGSize(width:329, height: 155)
        case CGSize(width: 375, height: 667):   return CGSize(width:321, height: 148)
        case CGSize(width: 360, height: 780):   return CGSize(width:329, height: 155)
        case CGSize(width: 320, height: 568):   return CGSize(width:292, height: 141)
        default:                                return CGSize(width:329, height: 155)
        }
    case .systemLarge:
        switch UIScreen.main.bounds.size {
        case CGSize(width: 428, height: 926):   return CGSize(width:364, height: 382)
        case CGSize(width: 414, height: 896):   return CGSize(width:360, height: 379)
        case CGSize(width: 414, height: 736):   return CGSize(width:348, height: 357)
        case CGSize(width: 390, height: 844):   return CGSize(width:338, height: 354)
        case CGSize(width: 375, height: 812):   return CGSize(width:329, height: 345)
        case CGSize(width: 375, height: 667):   return CGSize(width:321, height: 324)
        case CGSize(width: 360, height: 780):   return CGSize(width:329, height: 345)
        case CGSize(width: 320, height: 568):   return CGSize(width:292, height: 311)
        default:                                return CGSize(width:329, height: 345)
        }
        
    default:                                return CGSize(width:329, height: 345)
    }
}

如果您正在使用 swift UI,您可以像这样使用几何体 Reader 或使用环境 属性 包装器,您可以将它与三个进行比较尺寸 .systemSmall、Medium、Large

@Environment(\.widgetFamily) var widgetFamily