使用另一个类的 insertNewObject 添加的行未显示在表视图中

Posted

技术标签:

【中文标题】使用另一个类的 insertNewObject 添加的行未显示在表视图中【英文标题】:Row added using insertNewObject from another class does not show up in table view 【发布时间】:2020-02-24 02:24:57 【问题描述】:

我有一个 ViewController (CreateRowController),它有一个字符串的文本字段,然后将其提供给 MasterViewController 以创建一行。但是没有添加新行。我认为这与表视图更新有关,所以我尝试使用 reloadData() 代替 beginUpdates() 和 endUpdates(),但这并没有解决问题。我也尝试了不同的 tableView.insertRows,但它没有改变任何东西。

主视图控制器:

import UIKit

var className: String!

class MasterViewController: UITableViewController 

var detailViewController: DetailViewController? = nil
var objects = [] as Array

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view.


    navigationItem.leftBarButtonItem = editButtonItem

    let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(createNewRow(_:)))
    navigationItem.rightBarButtonItem = addButton
    if let split = splitViewController 
        let controllers = split.viewControllers
        detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
    


override func viewWillAppear(_ animated: Bool) 
    //clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
    super.viewWillAppear(animated)


@objc
func createNewRow (_ sender: Any) 
    let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let newViewController = storyBoard.instantiateViewController(withIdentifier: "createRowController") as! CreateRowController
    self.present(newViewController, animated: true, completion: nil)



func insertNewObject (_sender: Any) 
    print(className!)
    tableView.beginUpdates()
    objects.append(className!) //can change className
    tableView.insertRows(at: [IndexPath(row: objects.count-1, section: 0)], with: .automatic)
    tableView.endUpdates()


// MARK: - Segues

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == "showDetail" 
        if let indexPath = tableView.indexPathForSelectedRow 
            let object = objects[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
        
    


// MARK: - Table View

override func numberOfSections(in tableView: UITableView) -> Int 
    return 1


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return objects.count


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    let object = objects[indexPath.row] as! String
    cell.textLabel!.text = object.description
    return cell


override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
    // Return false if you do not want the specified item to be editable.
    return true


override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) 
    if editingStyle == .delete 
        objects.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .fade)
     else if editingStyle == .insert 
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    




创建视图控制器:

import UIKit

class CreateRowController: UIViewController 
@IBOutlet weak var nameOfEvent: UITextField!
@IBOutlet weak var numberOfClasses: UITextField!

var name = ""
var numClasses = 0

override func viewDidLoad() 
    super.viewDidLoad()

    // Do any additional setup after loading the view.


@IBAction func create(_ sender: Any) 
    self.name = nameOfEvent.text!
    self.numClasses = Int(numberOfClasses.text!)!
    className = self.name
    MasterViewController().insertNewObject(_sender: self)
    performSegue(withIdentifier: "createdRowToList", sender: self)


override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.destination is MasterViewController 
        className = self.name
    




谁能帮我解决这个问题?抱歉,我对 xcode 还很陌生。

编辑:我尝试了 vadian 的回答,所以如果您需要更多信息,请查看他的回答的评论

【问题讨论】:

【参考方案1】:

你犯了一个非常常见的错误。 MasterViewController() 创建一个新的控制器实例,它不是故事板中的实例。

删除该行

罢工>

MasterViewController().insertNewObject(_sender: self)

prepare(for 中获取MasterViewController 的正确实例,将名称分配给className 并调用insertNewObject

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if let masterController = segue.destination as? MasterViewController 
        masterController.className = self.name
        masterController.insertNewObject(nil)
    


但是我会声明 insertNewObject 将名称作为参数传递(begin/endUpdates 在这种情况下毫无意义)

func insertNewObject(name: String) 
    objects.append(name)
    tableView.insertRows(at: [IndexPath(row: objects.count-1, section: 0)], with: .automatic)

并将prepare(for 更改为

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if let masterController = segue.destination as? MasterViewController 
        masterController.insertNewObject(self.name)
    

【讨论】:

抱歉回复晚了,但我试过了,它似乎不起作用,尝试添加后表格是空白的。我把 print(objects) 放在追加之后,它确实打印了列表,所以我认为这可能与没有正确插入行有关?还有什么建议吗? 另外,我意识到当我执行 print(objects) 时,在尝试向对象添加其他内容后,它会替换原来的内容而不是追加内容。 在代码中没有证据表明对象被替换了。 是的,所以我不知道为什么会这样。并且该行没有显示在表格视图中。【参考方案2】:

好的,所以我在 MasterViewController 中发现了错误。当我进入那个场景时,第一位中的var objects = [] as Array 行显然会重置数组,所以我只是将它移出课堂,现在它可以工作了。

【讨论】:

以上是关于使用另一个类的 insertNewObject 添加的行未显示在表视图中的主要内容,如果未能解决你的问题,请参考以下文章

NSEntityDescription.insertNewObject 函数导致 Swift 3 崩溃

适配器方法惯用法

从另一个 DataFrame 添加一列

将 lambda 函数添​​加到类的符号表中

将 HashMap 的创建迭代为另一个 HashMap 中的值

如果我添加一个子视图控制器,并用它来呈现另一个视图控制器,整个根视图会被替换吗?