如何在不使用情节提要 segue 的情况下从单独的 UIViewController 将项添加到 UICollectio



我有一个UICollectionViewController显示一个称为倒计时的数据数组。我有一个以模式方式呈现的 UIView控制器,用户可以在其中创建新的倒计时。当用户点击"添加"(UIBarButtonItem(时,我想将UIViewController的新倒计时添加到UICollectionViewController上的数组(以及集合视图(。

我正在完全以编程方式构建我的应用程序(没有故事板文件(。我能找到的每篇文章/堆栈溢出帖子/YouTube教程都涉及使用UIStoryBoardSegue和/或将数据从CollectionView推送到另一个ViewController,但不是相反。我还没有找到以编程方式 100% 执行此操作的方法。

在我的狩猎过程中,我读到纯粹以编程方式创建和使用 segue 通常很糟糕。这是真的吗?如果是这样,我只需要使用委托吗?我将如何实现它?

下面是一些代码:

倒计时类:(具有其他属性,但为了简单起见,我只包含标题属性(

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
}

我尝试在使用 segue 的 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])
}

我会在这里使用委托。

创建一个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

相关内容

最新更新