SwiftUI 如何实现拖动上传图片?

23 min read

要在SwiftUI中实现拖动上传图片的功能,可以使用Drag and Drop API来处理拖放操作并实现文件上传。

首先,需要在View中添加一个DropDelegate来处理拖放操作:

struct ContentView: View {
    @State private var isDropped: Bool = false

    var body: some View {
        VStack {
            if isDropped {
                Text("文件已上传")
            } else {
                Text("将文件拖到此处")
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .onDrop(of: ["public.image"], isTargeted: nil) { (items) -> Bool in
            let itemProviders = items.itemProviders(for: ["public.image"])
            
            for itemProvider in itemProviders {
                if itemProvider.canLoadObject(ofClass: UIImage.self) {
                    itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
                        if let image = image as? UIImage {
                            // 将上传逻辑写在这里
                            DispatchQueue.main.async {
                                self.isDropped = true
                            }
                        }
                    }
                }
            }
            
            return true
        }
    }
}

上述代码中使用了一个isDropped的状态来控制文本的显示,如果文件已经上传,显示"文件已上传",否则显示"将文件拖到此处"。

然后,通过使用onDrop修饰符来监听拖放操作。其中,of参数指定了支持的数据类型(在这里是"public.image",表示只支持图像文件),isTargeted参数用于指示是否要高亮显示目标区域。

onDrop的闭包中,我们首先通过items.itemProviders(for:)方法获取所拖动的文件的实例,然后遍历每一个itemProvider,检查它是否可以加载为UIImage对象。如果是,则调用loadObject(ofClass:)方法将其加载为UIImage对象。

在获取到UIImage对象后,可以将其用于上传操作。具体的上传逻辑可以根据实际需求来实现。

最后,当文件上传完成后,我们使用DispatchQueue.main.asyncisDropped的状态设置为true,以便刷新界面显示已上传的文本。

这样就实现了简单的拖动上传图片的功能。