Как добавить элемент в UICollectionViewController из отдельного UIViewController без использования Storyboard segue? - PullRequest
0 голосов
/ 20 октября 2019

У меня есть UICollectionViewController, отображающий массив данных, называемых обратными отсчетами. У меня есть UIViewController, который представлен модально, где пользователь может создать новый обратный отсчет. Когда пользователь нажимает «Добавить» (UIBarButtonItem), я хочу добавить новый отсчет от UIViewController в массив (и, следовательно, представление коллекции) на UICollectionViewController.

Я создаю свое приложение полностью программно (без файлов раскадровки). Каждый пост / переполнение стека / учебник YouTube, который я могу найти, включает использование UIStoryBoardSegue и / или передачу данных из CollectionView в другой ViewController, но не наоборот. Я не нашел способа сделать это на 100% программно.

Во время охоты, которую я читал, вообще плохо создавать и использовать сегменты чисто программно. Это правда? Если это так, мне просто нужно использовать делегата? Как бы это реализовать?

Вот код:

Класс обратного отсчета: (имеет другие свойства, но для простоты я только включаю свойство title)

class Countdown {

    var title: String!

    init?(title: String!) {

        // Fail initialization if string is blank
        if title.isEmpty {
            return nil
        }

        // Initializing property
        self.title = title

    }

}

CountdownCollectionViewController: (это основной вид приложения)

class CountdownCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    var countdowns = [Countdown]()

    override func viewDidLoad() {
        super.viewDidLoad()

        loadSampleCountdowns()

    }

    private func loadSampleCountdowns() {

        // created 3 sample countdowns here

        countdowns += [countdown1, countdown2, countdown3]
    }

UIViewController: (представлен модально из CountdownsCollectionViewController)

class ViewController: UIViewController {

    var countdown: Countdown?

    // here I have a textfield property where the user enters a title for a new countdown 

    override func viewDidLoad() {
        super.viewDidLoad()


        self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", style: .done, target: self, action: #selector(addTapped))

    }


    @objc func addTapped(_ sender: UIBarButtonItem) {

        let title = titleTextField.text ?? ""

        countdown = Countdown(title: title)

        // here is where I want an action to send the newly created countdown to CountdownCollectionViewController

}

Я пытался использовать эту функцию в CountdownCollectionViewController, котораяиспользует переход, но, поскольку у меня нет раскадровок, это, конечно, не работает. Тем не менее, я думаю, что я иду в правильном направлении с кодом, который находится внутри него:

func unwindToCountdownList(_ sender: UIStoryboardSegue) {

    if let sourceViewController = sender.source as? ViewController, let countdown = sourceViewController.countdown {

        // Add a new countdown:
        let newIndexPath = IndexPath(row: countdowns.count, section: 0)

        // Append the new countdown from UIViewController to the array:
        countdowns.append(countdown) 

        // Add new item to collectionView:
        collectionView.insertItems(at: [newIndexPath])
}

1 Ответ

1 голос
/ 20 октября 2019

Я бы использовал здесь делегата.

Создайте ViewControllerDelegate:

protocol ViewControllerDelegate: class {
    func didCreateCountDown(vc: ViewController, countDown: CountDown)
}

Добавьте свойство делегата в ViewController и вызовите его в соответствующее время:

weak var delegate: ViewControllerDelegate?
@objc func addTapped(_ sender: UIBarButtonItem) {

    let title = titleTextField.text ?? ""

    countdown = Countdown(title: title)

    delegate.didCreateCountDown(vc: self, countDown: countDown)

    dismiss(animated: true, completion: nil)

}

Заставьте CountdownCollectionViewController соответствовать ViewControllerDelegate:

extension CountdownCollectionViewController : ViewControllerDelegate {
    func didCreateCountDown(vc: ViewController, countDown: CountDown) {
        // Add a new countdown:
        let newIndexPath = IndexPath(row: countdowns.count, section: 0)

        // Append the new countdown from UIViewController to the array:
        countdowns.append(countdown) 

        // Add new item to collectionView:
        collectionView.insertItems(at: [newIndexPath])
    }
}

Хотя вы этого не показали, в CountdownCollectionViewController должно быть место, которое вы называете present для представления ViewController:

let vc = ViewController()
...
present(vc, animated: true, completion: nil)

Непосредственно перед present вы можете установить self в качестве делегата:

vc.delegate = self
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...