SwiftUi Ondrag Preview当MacOS上的图像更改时,不会更新

发布于 2025-02-02 12:25:51 字数 2728 浏览 4 评论 0原文

我在图像>上有一个.ondrag。无论我自己是否提供预览自己,preview始终会被卡住显示出出现在第一个拖动上的imagensitemprovider本身运行良好,我访问了适当的数据,但不在preview中。

一个简单的示例(代码可用: https://github.com/github.com/godbout/ DragPreview

import SwiftUI


struct AppDetail {
    
    let bundleIdentifier: String
    let icon: NSImage
    
    init(bundleIdentifier: String) {
        self.bundleIdentifier = bundleIdentifier
        
        if
            let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleIdentifier),
            let representation = NSWorkspace.shared.icon(forFile: url.path).bestRepresentation(for: NSRect(x: 0, y: 0, width: 64, height: 64), context: nil, hints: nil)
        {
            self.icon = NSImage(size: representation.size)
            self.icon.addRepresentation(representation)
        } else {
            self.icon = NSApp.applicationIconImage!
        }
    }
    
}


struct ContentView: View {

    @State private var apps: [AppDetail] = [
        AppDetail(bundleIdentifier: "com.apple.Mail"),
        AppDetail(bundleIdentifier: "com.apple.MobileSMS"),
        AppDetail(bundleIdentifier: "com.apple.Safari"),
    ]
    
    var body: some View {
        VStack(alignment: .center) {
            Image(nsImage: apps.first == nil ? NSApp.applicationIconImage! : apps.first!.icon)
                .onDrag {
                    guard
                        let app = apps.first,
                        let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: app.bundleIdentifier)
                    else {
                        return NSItemProvider()
                    }
                                       
                    return NSItemProvider(object: url as NSURL)
                } preview: {
                    Text(apps.first == nil ? "no app" : apps.first!.bundleIdentifier)
                    Image(nsImage: apps.first == nil ? NSApp.applicationIconImage! : apps.first!.icon)
                }
            Button("next") {
                apps.removeFirst()
            }
            .disabled(apps.isEmpty)
        }
        .frame(width: 200, height: 200)
        .padding()   
    }

}

我做错了什么?这可能是(不)Swiftui错误吗?如果Preview实际上是静态的,并且仅在第一个拖动中呈现,则我该如何更改代码,以便我获得当前image> image preview >?

谢谢。

I'm having an .onDrag on an Image. Whether I provide a preview myself or not, the preview always gets stuck to show the Image that appeared on the first drag. The NSItemProvider itself works well and I access the proper data, but not within the preview.

enter image description here

A simple example (code available here: https://github.com/godbout/DragPreview)

import SwiftUI


struct AppDetail {
    
    let bundleIdentifier: String
    let icon: NSImage
    
    init(bundleIdentifier: String) {
        self.bundleIdentifier = bundleIdentifier
        
        if
            let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleIdentifier),
            let representation = NSWorkspace.shared.icon(forFile: url.path).bestRepresentation(for: NSRect(x: 0, y: 0, width: 64, height: 64), context: nil, hints: nil)
        {
            self.icon = NSImage(size: representation.size)
            self.icon.addRepresentation(representation)
        } else {
            self.icon = NSApp.applicationIconImage!
        }
    }
    
}


struct ContentView: View {

    @State private var apps: [AppDetail] = [
        AppDetail(bundleIdentifier: "com.apple.Mail"),
        AppDetail(bundleIdentifier: "com.apple.MobileSMS"),
        AppDetail(bundleIdentifier: "com.apple.Safari"),
    ]
    
    var body: some View {
        VStack(alignment: .center) {
            Image(nsImage: apps.first == nil ? NSApp.applicationIconImage! : apps.first!.icon)
                .onDrag {
                    guard
                        let app = apps.first,
                        let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: app.bundleIdentifier)
                    else {
                        return NSItemProvider()
                    }
                                       
                    return NSItemProvider(object: url as NSURL)
                } preview: {
                    Text(apps.first == nil ? "no app" : apps.first!.bundleIdentifier)
                    Image(nsImage: apps.first == nil ? NSApp.applicationIconImage! : apps.first!.icon)
                }
            Button("next") {
                apps.removeFirst()
            }
            .disabled(apps.isEmpty)
        }
        .frame(width: 200, height: 200)
        .padding()   
    }

}

Anything I'm doing wrong? Could this be a(nother) SwiftUI bug? If the preview is actually static and only rendered at the first drag, how could I change the code so that I get the preview of my current Image?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情话墙 2025-02-09 12:25:51

我在@asperi的评论中读到某个地方,即在INIT上只创建了一次Drag Preview。因此,如果您向图像添加.ID,则迫使Redraw和Reinit的预览:

            Image(nsImage: apps.first == nil ? NSApp.applicationIconImage! : apps.first!.icon)
                .id(apps.first?.bundleIdentifier) // here
                .onDrag { ...

I read somewhere in a comment by @Asperi that the drag preview is only created once at init. So if you add an .id to the image it forces a redraw and reinit of preview:

            Image(nsImage: apps.first == nil ? NSApp.applicationIconImage! : apps.first!.icon)
                .id(apps.first?.bundleIdentifier) // here
                .onDrag { ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文