启用 OS18 色调模式时,iOS 小部件图像不显示

问题描述 投票:0回答:1

我正在实现一个 iOS 小部件。从照片中检索图像,并与一些基本功能按钮(此处未包括)一起显示在小部件中。

当设备显示首选项在各种操作系统版本的所有设备上正常时,小部件可以在本地或从 TestFlight 正常构建。

但是,在 iOS 18 上,有一个“色调”功能,允许对跳板图标和小部件进行着色。当启用此模式时,图像将不会显示。

我尝试过转换为 JPG、PNG 和 TIFF。我尝试过转换为单色和黑白。我尝试过将尺寸减小到非常小。

在每种情况下,转换后的图像在正常模式下都能正确显示,但在启用色调的情况下不会显示。

图像框架出现,但操作系统本质上是用色调颜色覆盖整个图像本身。

下面是最简单的 Widget 布局显示图像的代码。没有什么特别的事情发生。图像根本不会显示。

我已经很长时间没有向这个伟大网站上的专家寻求建议了,但这绝对值得这个问题。

这就是启用色调后图像的显示方式。 Basic widget displaying blank photo with Tint Mode enabled on OS 18 device

struct Provider: AppIntentTimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(), configuration: ConfigurationAppIntent(), screenshot: nil)
    }

    func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
        let screenshot = PhotosManager.shared.loadMostRecentScreenshotThumb()
        return SimpleEntry(date: Date(), configuration: configuration, screenshot: screenshot)
    }

    func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
        let screenshot = PhotosManager.shared.loadMostRecentScreenshotThumb()
        let currentDate = Date()
        let nextRefreshDate = Calendar.current.date(byAdding: .minute, value: 30, to: currentDate)!
        let entry = SimpleEntry(date: currentDate, configuration: configuration, screenshot: screenshot)
        let timeline = Timeline(entries: [entry], policy: .after(nextRefreshDate))
        return timeline
    }
}

struct SimpleEntry: TimelineEntry {
    let date: Date
    let configuration: ConfigurationAppIntent
    let screenshot: UIImage?
}

struct WidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        HStack {
            if let screenshot = entry.screenshot {
                Image(uiImage: screenshot)
                    .widgetAccentable()
            } else {
                Image(systemName: "photo")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .padding(5)
                }
            }  
        }
    }
}

struct DS_Widget: Widget {
    let kind: String = "Shot_Widget"

    var body: some WidgetConfiguration {
        AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
            WidgetEntryView(entry: entry)
                .containerBackground(Color.clear, for: .widget)
        }
        .contentMarginsDisabled()
    }
}

这是从照片中检索照片的代码。

func loadMostRecentScreenshotThumb() -> UIImage? {
    let result = PHAsset.fetchAssets(with: .image, options: getOptions())
    if let asset = result.firstObject {
        let imageManager = PHImageManager.default()
        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = true
        requestOptions.deliveryMode = .fastFormat

        var image: UIImage?
        imageManager.requestImage(for: asset, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: requestOptions) { result, _ in
            image = result
        }
        return image
    }
    return nil
}

添加注释:更糟糕的是,当我撰写此内容时,我更改了从照片中检索的图像的大小以直接请求 100x100,并且图像出现并且它是有色的!以为我刚刚解决了这个问题,我将其更改为 120x120 进行测试,图像又消失了并且无法显示。这是我第一次看到启用色调模式时显示的图像。

这是一个非常有趣又令人沮丧的问题。任何帮助都会很棒,谢谢!

swift swiftui widget uiimage ios18
1个回答
0
投票

在这种情况下您不应该使用

.widgetAccentable()
.widgetAccentable()
将图像的所有非透明区域转换为主屏幕色调颜色。

如果您想在不修改其颜色的情况下显示图像,即使在有色环境中,您也应该使用,

Image(uiImage: screenshot)
    .widgetAccentedRenderingMode(.fullColor)

如果您想在某种程度上尊重用户对色调颜色的选择,请传入

.accentedDesaturated
而不是
.fullColor

像这样的图像:

enter image description here

如果我选择微红色作为色调,将显示如下:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.