如何从图像选择器中获取图像并显示到添加表单中?
How to get the image from image picker and display into a add form?
我有下面的结构来处理图像选择器,但我无法将选择的图像传递给要显示的视图。下面选定的路径正确地打印了文件的位置,但是如何将这个选定的文件分配给视图中的图片?
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)
根据下面的响应更新了上面的代码。
提前致谢。
您可以使用 Binding
将数据从 child 视图传递回 parent:
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)
}
}
}
}
请注意,在 child 中,它是 @Binding
,但在 parent 中,它是 @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 或任何东西进行任何错误处理
我有下面的结构来处理图像选择器,但我无法将选择的图像传递给要显示的视图。下面选定的路径正确地打印了文件的位置,但是如何将这个选定的文件分配给视图中的图片?
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)
根据下面的响应更新了上面的代码。
提前致谢。
您可以使用 Binding
将数据从 child 视图传递回 parent:
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)
}
}
}
}
请注意,在 child 中,它是 @Binding
,但在 parent 中,它是 @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 或任何东西进行任何错误处理