SwiftUI:在用户使用 DocumentPicker 选择文件后显示数组中的文件 url
SwiftUI: Display file url from Array after user Picks file using DocumentPicker
我遵循了有关从用户选择的文档中获取 Url 并能够将其显示在视图上的教程。我现在的问题是我想将那些 Url 添加到数组中。然后从数组中获取项目并将它们打印到视图上。它的工作方式是用户按下一个按钮,sheet 随文件应用程序弹出。用户可以在那里选择文档。用户选择文档后,Url 将打印在视图上。要打印 Url 是使用此
//if documentUrl has an Url show it on the view
If let url= documentUrl{
Text(url.absoluteString)
}
问题是当我做同样的事情时
If let url= documentUrl
在 Url 甚至添加到数组之前 运行 并且应用程序崩溃
这是完整的代码
//Add the Urls to the array
class Article: ObservableObject{
var myArray:[String] = []
}
struct ContentView: View {
@State private var showDocumentPicker = false
@State private var documentUrl:URL?
@State var myString:URL?
@ObservedObject var userData:Article
// Func for onDismiss from the Sheet
func upload() {
// add the Url to the Array
DispatchQueue.main.async{
userData.myArray.append(documentUrl!.absoluteString)
}
}
var body: some View {
VStack{
//If have Url reflect that on the View
if let url = documentUrl{
//Works
Text(url.absoluteString)
//doesntwork
Text(userData.myArray[0])
}
}
Button(action:{showDocumentPicker.toggle()},
label: {
Text("Select your file")
})
.sheet(isPresented: $showDocumentPicker, onDismiss: upload )
{
DocumentPicker(url: $documentUrl)
}
}
}
我想做的主要事情是在用户选择文档后或 sheet 消失后将 ulrs 显示到视图中。因此,如果用户选择 1 Url,则只打印一个。如果之后选择另一个,则显示 2 个,依此类推。
这是用于选择文档的documentPicker代码
struct DocumentPicker : UIViewControllerRepresentable{
@Binding var url : URL?
func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
//initialize a UI Document Picker
let viewController = UIDocumentPickerViewController(forOpeningContentTypes: [.epub])
viewController.delegate = context.coordinator
print("1")
return viewController
}
func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {
print("Swift just updated ")
print("2")
}
}
extension DocumentPicker{
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator:NSObject, UIDocumentPickerDelegate{
let parent: DocumentPicker
init(_ documentPicker: DocumentPicker){
self.parent = documentPicker
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first else{return}
parent.url = url
print("3")
}
}
}
不确定我是否没有以正确的方式处理这个问题?我查看了不同的教程,但找不到任何内容。
可观察对象没有更改触发器。要通知可观察对象已更改,请使用以下示例之一:
class Article: ObservableObject {
@Published var myArray:[String] = []
}
或
class Article: ObservableObject {
private(set) var myArray:[String] = [] {
willSet {
objectWillChange.send()
}
}
func addUrl(url: String) {
myArray.append(url)
}
}
官方文档:https://developer.apple.com/documentation/combine/observableobject
使用.fileImporter presentation modifire (above ios 14)
.fileImporter(isPresented: $showDocumentPicker,
allowedContentTypes: [.image],
allowsMultipleSelection: true)
{ result in
// processing results Result<[URL], Error>
}
我遵循了有关从用户选择的文档中获取 Url 并能够将其显示在视图上的教程。我现在的问题是我想将那些 Url 添加到数组中。然后从数组中获取项目并将它们打印到视图上。它的工作方式是用户按下一个按钮,sheet 随文件应用程序弹出。用户可以在那里选择文档。用户选择文档后,Url 将打印在视图上。要打印 Url 是使用此
//if documentUrl has an Url show it on the view
If let url= documentUrl{
Text(url.absoluteString)
}
问题是当我做同样的事情时
If let url= documentUrl
在 Url 甚至添加到数组之前 运行 并且应用程序崩溃
这是完整的代码
//Add the Urls to the array
class Article: ObservableObject{
var myArray:[String] = []
}
struct ContentView: View {
@State private var showDocumentPicker = false
@State private var documentUrl:URL?
@State var myString:URL?
@ObservedObject var userData:Article
// Func for onDismiss from the Sheet
func upload() {
// add the Url to the Array
DispatchQueue.main.async{
userData.myArray.append(documentUrl!.absoluteString)
}
}
var body: some View {
VStack{
//If have Url reflect that on the View
if let url = documentUrl{
//Works
Text(url.absoluteString)
//doesntwork
Text(userData.myArray[0])
}
}
Button(action:{showDocumentPicker.toggle()},
label: {
Text("Select your file")
})
.sheet(isPresented: $showDocumentPicker, onDismiss: upload )
{
DocumentPicker(url: $documentUrl)
}
}
}
我想做的主要事情是在用户选择文档后或 sheet 消失后将 ulrs 显示到视图中。因此,如果用户选择 1 Url,则只打印一个。如果之后选择另一个,则显示 2 个,依此类推。 这是用于选择文档的documentPicker代码
struct DocumentPicker : UIViewControllerRepresentable{
@Binding var url : URL?
func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
//initialize a UI Document Picker
let viewController = UIDocumentPickerViewController(forOpeningContentTypes: [.epub])
viewController.delegate = context.coordinator
print("1")
return viewController
}
func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {
print("Swift just updated ")
print("2")
}
}
extension DocumentPicker{
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator:NSObject, UIDocumentPickerDelegate{
let parent: DocumentPicker
init(_ documentPicker: DocumentPicker){
self.parent = documentPicker
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first else{return}
parent.url = url
print("3")
}
}
}
不确定我是否没有以正确的方式处理这个问题?我查看了不同的教程,但找不到任何内容。
可观察对象没有更改触发器。要通知可观察对象已更改,请使用以下示例之一:
class Article: ObservableObject {
@Published var myArray:[String] = []
}
或
class Article: ObservableObject {
private(set) var myArray:[String] = [] {
willSet {
objectWillChange.send()
}
}
func addUrl(url: String) {
myArray.append(url)
}
}
官方文档:https://developer.apple.com/documentation/combine/observableobject
使用.fileImporter presentation modifire (above ios 14)
.fileImporter(isPresented: $showDocumentPicker,
allowedContentTypes: [.image],
allowsMultipleSelection: true)
{ result in
// processing results Result<[URL], Error>
}