I'm trying to open a picker file menu. To perform this, I create a class like so:
class pickerView: UIDocumentPickerViewController, UIDocumentPickerDelegate, LTHM_Pickerable {
func importTapped() {
//Create a picker specifying file type and mode
let documentPicker = UIDocumentPickerViewController(documentTypes: [String(kUTTypePNG)], in: .import)
documentPicker.delegate = self
documentPicker.allowsMultipleSelection = false
documentPicker.modalPresentationStyle = .fullScreen
present(documentPicker, animated: true, completion: nil)
}
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard controller.documentPickerMode == .import, let url = urls.first, let image = UIImage(contentsOfFile: url.path) else { return }
controller.dismiss(animated: true)
}
public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
controller.dismiss(animated: true)
}
}
I want to call the function "importTapped" in a function with is in a class inheriting from UITableViewCell.
class LTHM_Sticker_Cell: UITableViewCell {
@IBAction func createStickerOnTAp(_ sender: UIButton, forEvent event: UIEvent) {
//CALL IMPORTTAPPED HERE
}
}
can you please help me? I have tried with a protocol, but I'm not sure...
Having a UIDocumentPickerViewController
subclass that creates an instance of the regular UIDocumentPickerViewController
is a bit confusing, and it's missing a clear means to actually present it. You might want to try this protocol/delegate solution instead:
Define a protocol
protocol PickerPresenter: UIViewController {
func presentPicker()
}
Create the view controller class that will contain your table view
class MyViewController: UIViewController {
// your implementation
}
Conform your view controller to the protocol
extension MyViewController: PickerPresenter {
func presentPicker() {
let documentPicker = UIDocumentPickerViewController(documentTypes: [String(kUTTypePNG)], in: .import)
documentPicker.delegate = self
documentPicker.allowsMultipleSelection = false
documentPicker.modalPresentationStyle = .fullScreen
present(documentPicker, animated: true, completion: nil)
}
}
And to be the picker delegate
extension MyViewController: UIDocumentPickerDelegate {
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard controller.documentPickerMode == .import, let url = urls.first, let image = UIImage(contentsOfFile: url.path) else { return }
// do something with the selected image
controller.dismiss(animated: true)
}
public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
controller.dismiss(animated: true)
}
}
Pass a reference to the view controller when you're dequeuing the cell
extension MyViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell") as! LTHM_Sticker_Cell
cell.delegate = self
return cell
}
}
Finally, your cell class has a weak reference to the delegate, and calls it's delegate method when the button is tapped
class LTHM_Sticker_Cell: UITableViewCell {
weak var delegate: PickerPresenter?
@IBAction func createStickerOnTAp(_ sender: UIButton, forEvent event: UIEvent) {
delegate?.presentPicker()
}
}