Передача данных в контроллер основного представления с делегатом в swift для macOS - PullRequest
0 голосов
/ 14 мая 2019

У меня есть контроллер основного вида 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
        }
    }

1 Ответ

0 голосов
/ 14 мая 2019

Скорее всего, проблема возникает из-за того, что didSet вызывается раньше, чем viewDidLoad

Но в этом случае вам не нужен протокол / делегат.

Как * 1007Контроллер * AddBook представлен модально с использованием свойства presentingViewController.
Параметр sender в методе делегата не используется.

let parent = presentingViewController as! ViewController
parent.addBook(_ data: [String])

Я бы даже создал книгу в дополненииконтроллер и возврат

parent.addBook(_ book: Book)
...