Как обновить tableviewcell, используя кнопку назад? - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть этот tableviewcontroller и detailviewcontroller, который имеет текстовое поле, когда пользователь щелкает ячейку tableview, он переходит в текстовое поле, и пользователь может редактировать содержимое !! Как обновить табличное представление новым содержимым в текстовом поле с помощью кнопки «Назад»?

let sectionTitles = ["ongoing","Done"]
var list = [String]()

class MasterViewController: UITableViewController {

    var detailViewController: DetailViewController? = nil
    var objects = sectionTitles.map({_ in return [Any]()})

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        navigationItem.leftBarButtonItem = editButtonItem

        let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
        navigationItem.rightBarButtonItem = addButton

        if let split = splitViewController {
            let controllers = split.viewControllers
            detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }
    }

    @objc
    func insertNewObject(_ sender: Any) {
        objects[0].insert("Task 1", at: 0)
        let indexPath = IndexPath(row: 0, section: 0)
        tableView.insertRows(at: [indexPath], with: .automatic)
    }

    // MARK: - Segues

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail" {
            if let indexPath = tableView.indexPathForSelectedRow {
                let object = objects[indexPath.section][indexPath.row] as! String
                let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
                controller.detailItem = object

                controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
                controller.navigationItem.leftItemsSupplementBackButton = true
            }
        }
    }
}

class DetailViewController: UIViewController,UINavigationControllerDelegate {

    @IBOutlet weak var detailDescription: UITextField!

    func configureView() {

        // Update the user interface for the detail item.
        if let detail = detailItem {

            if let label = detailDescription {
                label.text = detail.description
                list.append(label.text!)
            }
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 29 апреля 2018

Когда вы нажмете кнопку «назад», будет вызван viewWillAppear , его View Controller Lifecycle

например

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.tableView.reloadData()
    }
0 голосов
/ 29 апреля 2018

Я рекомендую использовать функцию обратного вызова для обновления модели и перезагрузки строки. Обратный вызов вызывается в viewDidDisappear. Код в замыкании проверяет, отличаются ли значения, обновляет модель и при необходимости перезагружает строку.

  • В DetailViewController создайте обратный вызов

    var callback : ((String)->())?
    
    • В viewDidDisappear вызовите обратный вызов (или, может быть, уже в viewWillDisappear)

      override func viewDidDisappear(_ animated: Bool) {
          super.viewDidDisappear(animated)
          callback?(detailDescription.text!)
      }
      
  • В MasterViewController добавить замыкание в prepare(for

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail" {
            if let indexPath = tableView.indexPathForSelectedRow {
                let object = objects[indexPath.section][indexPath.row] as! String
                let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
                controller.detailItem = object
                controller.callback = { [weak self] newValue in 
                   if object != newValue {
                       self?.objects[indexPath.section][indexPath.row] = newValue
                       self?.tableView.reloadRows(at: [indexPath], with: .automatic)
                    }
                }
                controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
                controller.navigationItem.leftItemsSupplementBackButton = true
            }
        }
    }
    
0 голосов
/ 29 апреля 2018

Вы можете использовать шаблон делегата:

protocol DetailViewDelegate: class {
    func detailViewDidUpdate(from: String?, to: String?)
}

class DetailViewController : UIViewController {

    var detailItem: String?

    weak var delegate: DetailViewDelegate?

    @IBOutlet weak var textField: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()
        self.textField.text = detailItem
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.delegate?.detailViewDidUpdate(from: detailItem, to: textField.text)
    }
}

Тогда в вашем MasterViewController :

extension MasterViewController: DetailViewDelegate {
    func detailViewDidUpdate(from: String?, to: String?) {
        guard let originalValue = from, let newValue = to else {
            return
        }

        if let indexPath = self.objects.index(of: originalValue) {
            self.objects[indexPath] = newValue
            // We assume here that there is only one section
            let newIndexPath = IndexPath(row: indexPath, section: 0)
            self.tableView.reloadRows(at: [newIndexPath], with: .automatic)
        }
    }
}

Не забудьте назначить переменную делегата DetailViewController в вашем MasterController prepare (для segue: UIStoryboardSegue, sender: Any?) method

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