Похоже, вы назначаете класс ViewController
как первому контроллеру (который содержит табличное представление), И второму контроллеру (с текстовым полем).
Это не сработает.
Добавьте этот класс в свой проект, назначьте его как настраиваемый класс контроллера представления «Новый элемент» и подключите @IBOutlet
и @IBAction
:
class NewItemViewController: UIViewController {
// callback closure to tell the VC holding the table view
// that the Add button was tapped, and to
// "send back" the new text
var callback: ((String) -> ())?
@IBOutlet weak var textField: UITextField!
@IBAction func add(_ sender: Any) {
let item: String = textField.text!
callback?(item)
textField.text = ""
}
}
Затем измените свой ViewController
класс на следующий:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var editButton: UIBarButtonItem!
var tableViewData = ["Apple", "Banana", "Orange", "Peach", "Pear"]
override func viewDidLoad() {
super.viewDidLoad()
// if you're not already seeing "Apple", "Banana", "Orange", "Peach", "Pear"
// add these two lines
//tableView.dataSource = self
//tableView.delegate = self
}
// MARK: Tableview methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableViewData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = tableViewData[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// print(tableViewData[indexPath.row])
}
// Allows reordering of cells
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
// Handles reordering of cells
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item = tableViewData[sourceIndexPath.row]
tableViewData.remove(at: sourceIndexPath.row)
tableViewData.insert(item, at: destinationIndexPath.row)
}
// Allow the user to delete cells
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCell.EditingStyle.delete {
tableViewData.remove(at: indexPath.row)
tableView.reloadData()
}
}
// MARK: IBActions
@IBAction func edit(_ sender: Any) {
tableView.isEditing = !tableView.isEditing
switch tableView.isEditing {
case true:
editButton.title = "Done"
case false:
editButton.title = "Edit"
}
}
// when "New Item" button is tapped, it will segue to
// NewItemViewController... set the callback closure here
// prepare for segue is called when you have created a segue to another view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// error checking is always a good idea
// this properly unwraps the destination controller and confirms it's
// an instance of NewItemViewController
if let vc = segue.destination as? NewItemViewController {
// callback is a property we added to NewItemViewController
// we declared it to return a String
vc.callback = { item in
self.tableViewData.append(item)
self.tableView.reloadData()
self.navigationController?.popViewController(animated: true)
}
}
}
}
Когда вы нажимаете кнопку «Добавить элемент», мы предполагаем, что вы подключили его для перехода к Контроллер представления «Новый элемент». Реализуя:
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
, мы получим ссылку на контроллер представления «Новый элемент», который вот-вот появится, и назначим ему «закрытие обратного вызова».
Когда мы набираем текст и нажимаем кнопку «Добавить» в следующем контроллере, он «перезвонит» первому контроллеру, передавая только что набранный текст. В этом мы обновим массив данных, перезагрузим таблицу и вернемся в стек навигации.