У меня есть контроллер основного вида ViewController
и дополнительный: AddBookSheetViewController
. Второй контроллер представления представлен в виде листа и должен обеспечивать функцию очистки веб-сайта из-за идентификатора пользовательского ввода и последующей передачи обработанных данных обратно ViewController.
Я нашел этот связанный ответ, который описывает мою проблему в обратном порядке и поэтому выглядит многообещающим. Я должен быть в состоянии идти оттуда, верно?
Передача данных из ViewController в TabViewController
Увы, данные не передаются. Вот мой код:
@objc protocol AddBookSheetViewControllerDelegate {
func addBookFromExtern(sender: AddBookSheetViewController, data: [String])
}
class AddBookSheetViewController: NSViewController {
weak var delegate: AddBookSheetViewControllerDelegate?
@IBOutlet weak var isbnSheetTextField: NSTextField!
var bibTex = "" {
didSet {
//: sets as expected
print(oldValue, "replaced for new:", bibTex)
let bookFromBibtex = BookFromBibtex()
let texData = bookFromBibtex.getInfo(bibtex: bibTex)
//: prints
print("now we've reached delegate")
//: nothing happens on the other side
self.delegate?.addBookFromExtern(sender: self, data: texData)
//: prints
print("now we've passed delegate")
}
}
override func viewDidLoad() {
super.viewDidLoad()
//
//: might this be problem? "parent"?
//
if let viewController = parent as? ViewController {
self.delegate = viewController
}
}
@IBAction func getBookSheetButton(_ sender: Any) {
if isbnSheetTextField.stringValue != "" {
//: .letterCount is a String extension
if isbnSheetTextField.stringValue.letterCount <= 0 {
//: scrape() does the URLSession and regex work
scrape(isbn: isbnSheetTextField.stringValue)
//: cont'd in bibTex didSet
} else { print("Unvalid ISBN.")}
} else {print ("Enter ISBN.") }
}
}
class ViewController: NSViewController, NSWindowDelegate, AddBookSheetViewControllerDelegate {
func addBookFromExtern(sender: AddBookSheetViewController, data: [String]) {
let newBook = Book(author: data[0], title: data[1], lentBy: "", signature: "", comment: "", isbn: "123", lentDate: "", creationDate: Date())
self.BookArrayController.addObject(newBook)
print("signal received") //: doesn't get triggered
}
}
Другие предложили другие методы, например, здесь , но, похоже, они относятся только к iOS или я не смог их реализовать.
Можете ли вы определить проблему? (Возможно, в функции AddBookSheetViewController
s viewDidLoad()
и, возможно, конкретно относится к идентификатору «parent»?) Спасибо!
- Изменить
Ответ
@ vadian дал решающее понимание и, конечно, более элегантное решение в целом. Лучше всего использовать его ответ. В текущей настройке это работает:
override func viewDidLoad() {
super.viewDidLoad()
//: or presentingViewController
if let viewController = presenting as? ViewController {
self.delegate = viewController
}
}
это также работает:
override func viewDidLoad() {
super.viewDidLoad()
let mainViewController = presenting as! ViewController
self.delegate = mainViewController
}
}
Однако, это вызывает некоторые сбои в NSTableView основного vc ViewController (где данные развертываются).
Добавление
/ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** /
Nota Bene :
Согласно @vadian, следующее является особенно плохой практикой, то есть неправильным и настолько значительным, что он предположил, что я полностью удалил его. Я оставлю это в образовательных целях.
/ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * * ** ** ** ** ** /
Непосредственно перед ответом @ vadian у меня был полу-успех, когда я попробовал это, прочитав следующее: делегат / протокол master-детали macOS Swift не работает
То есть я смог перейти на основной vc ViewController, но приложение неожиданно завершилось с нулем. (Я не понял почему). Замена AddBookSheetViewControllerDelegate
на ViewController
привела к тому же самому поведению ..
override func viewDidLoad() {
super.viewDidLoad()
let mainViewController = ViewController()
if let viewController = mainViewController as? AddBookSheetViewControllerDelegate {
self.delegate = viewController
}
}