【问题标题】:How to get the image from image picker and display into a add form?如何从图像选择器中获取图像并显示到添加表单中?
【发布时间】:2021-03-15 15:28:14
【问题描述】:

我有下面的结构来处理图像选择器,但我无法将选择的图像传递给要显示的视图。下面选择的路径正确打印文件的位置,但是如何将此选定的文件分配给图片到视图中?

    struct FileView: View {
    var body: some View {
        Button("Select File") {
            let openPanel = NSOpenPanel()
            openPanel.prompt = "Select File"
            openPanel.allowsMultipleSelection = false
            openPanel.canChooseDirectories = false
            openPanel.canCreateDirectories = false
            openPanel.canChooseFiles = true
            openPanel.allowedFileTypes = ["png","jpg","jpeg"]
            openPanel.begin { (result) -> Void in
                if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
                    let selectedPath = openPanel.url!.path
                    print(selectedPath)
                    
                }
            }
        }
    }
}

在我显示所选图像的位置下方:

struct NewPost: View {
    
    @Environment(\.presentationMode) var presentationMode
    
    var postToEdit: Item?
    var viewContext: NSManagedObjectContext
    ...
    @State var fileUrl: URL?
    
    var header: String {
        postToEdit == nil ? "Create Post" : "Edit Post"
    }
    
    
    var body: some View {

    ...Form Code

    // Displaying Image if its selected...
                
Section(header: Text("Picture").foregroundColor(Color("blue")).font(.title2)) {
                        
if let fileUrl = fileUrl, let img = NSImage(contentsOf: fileUrl) {
                            
    Image(nsImage: img)
        .resizable()
        .scaledToFill()
        .clipShape(Circle())
        .overlay(Circle().stroke(Color.white, lineWidth: 1))
        .opacity(1)
        .frame(minWidth: 120, maxWidth: 120, minHeight: 120, maxHeight: 120)
                            
     }
                        
 if pic.count != 0 {
                            
          Image(nsImage: NSImage(data: pic)!)
              .resizable()
              .scaledToFill()
              .clipShape(Circle())
              .overlay(Circle().stroke(Color.white, lineWidth: 1))
              .opacity(1)
              .frame(minWidth: 120, maxWidth: 120, minHeight: 120, maxHeight: 120)
         }
     }
     .cornerRadius(10)

根据下面的响应更新了上面的代码。

提前致谢。

【问题讨论】:

    标签: swift macos swiftui imagepicker


    【解决方案1】:

    您可以使用Binding 将数据从子视图传回父视图:

    struct FileView: View {
        @Binding var fileUrl : URL?
        
        var body: some View {
            Button("Select File") {
                let openPanel = NSOpenPanel()
                openPanel.prompt = "Select File"
                openPanel.allowsMultipleSelection = false
                openPanel.canChooseDirectories = false
                openPanel.canCreateDirectories = false
                openPanel.canChooseFiles = true
                openPanel.allowedFileTypes = ["png","jpg","jpeg"]
                openPanel.begin { (result) -> Void in
                    if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
                        fileUrl = openPanel.url
                    }
                }
            }
        }
    }
    
    struct ContentView: View {
        @State var fileUrl: URL?
        
        var body: some View {
            VStack {
                FileView(fileUrl: $fileUrl)
                if let fileUrl = fileUrl, let image =  NSImage(contentsOf: fileUrl) {
                    Image(nsImage: image)
                }
            }
        }
    }
    

    请注意,在子级中,它是@Binding,但在父级中,它是@State

    更新版本,使用Data

    struct FileView: View {
        @Binding var fileData : Data?
        
        var body: some View {
            Button("Select File") {
                let openPanel = NSOpenPanel()
                openPanel.prompt = "Select File"
                openPanel.allowsMultipleSelection = false
                openPanel.canChooseDirectories = false
                openPanel.canCreateDirectories = false
                openPanel.canChooseFiles = true
                openPanel.allowedFileTypes = ["png","jpg","jpeg"]
                openPanel.begin { (result) -> Void in
                    if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
                        guard let url = openPanel.url, let data = try? Data(contentsOf: url) else {
                            //handle errors here
                            return
                        }
                        fileData = data
                    }
                }
            }
        }
    }
    
    struct ContentView: View {
        @State var fileData: Data?
        
        var body: some View {
            VStack {
                FileView(fileData: $fileData)
                if let fileData = fileData, let image =  NSImage(data: fileData) {
                    Image(nsImage: image)
                }
            }
        }
    }
    

    注意:显然,对于无法从 URL 或本示例中的任何内容进行读取,没有进行任何错误处理

    【讨论】:

    • 完美,非常感谢,但我仍然只有一个问题。此表单是一个 .sheet,在编辑时接收来自列表视图的数据,而不是新的,图像作为数据保存到之前分配为上面代码的 CoreData 中。现在编辑时如何显示图像?我正在使用我拥有的当前属性更新上面的代码。
    • 从您的更新中我不清楚您要做什么。您是否只需要我更新我的答案以使用Data 而不是URL
    • 我只是希望您能帮助我们了解编辑帖子时的最佳处理方式,因为在您的帮助下,我可以发布新帖子。编辑帖子时,没有显示核心数据的图像,我不知道如何处理它。
    • 对不起,我仍然不确定这到底是什么意思,所以我只是猜测。您如何将原始图像中的Data 作为参数(非绑定)发送并显示它,除非fileUrl 绑定中有数据?
    • 抱歉没说清楚。正如您在上面的编辑代码中看到的那样,我遵循了您的建议,但现在我不知道如何保存一个或另一个,具体取决于创建新帖子(使用 fileURL 图像)或编辑帖子(NSImage:(数据:图片)即将到来来自核心数据)。 :(
    猜你喜欢
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 2021-01-06
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 2019-10-07
    相关资源
    最近更新 更多