tableView.reloadData()不调用cellForRowAtindexPath()

时间:2018-10-14 11:55:47

标签: ios swift uitableview

我正在尝试实现tableView列表,其中第一行用于将项目添加到该列表中

为此,我为第一个单元格和TableView创建了两个单独的类。 enter image description here

单元格类使用协议TextFieldDelegate将输入的值传递给TableView类

protocol TextFieldDelegate {
    func saveProduct (newProduct: Product)
}

class TextFieldCell: UITableViewCell {

    @IBOutlet weak var insertProduct: UITextField!
    @IBOutlet weak var insertQuantity: UITextField!
    
    
    var delegate: TextFieldDelegate?
   
    
    override func awakeFromNib() {
        let vc = ListViewController()
        self.delegate = vc
    }

    @IBAction func addButtonPressed(_ sender: UIButton) {
        
        let newProduct = Product()
        
        if let productText = insertProduct.text{
            newProduct.name = productText
        } else{
            fatalError("Product name is not inserted")
        }
        
        if let quantityText = insertQuantity.text{
            newProduct.quantity = Int(quantityText) ?? 0
        } else{
            fatalError("Product quantity is not inserted")
        }
        
        delegate?.saveProduct(newProduct: newProduct)
        insertProduct.text = ""
        insertQuantity.text = ""
    }
}

TableView类符合上述协议,将数据保存到Realm数据库并重新加载表

class ListViewController: UITableViewController, TextFieldDelegate {
    

    let realm = try! Realm()
    var products: Results<Product>?
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        loadProducts()
    }
    
    
    //MARK: - TableView DataSource Methods
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        if let numberOfCell = products?.count{
            
            guard numberOfCell == 0 else {
                print("number of rows working - \(numberOfCell)")
                return numberOfCell + 1 }
            return 1
        }
        else {
            return 1
        }
        
    }    

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print("cell for row started")
        if indexPath.row == 0 {
            let textCell = tableView.dequeueReusableCell(withIdentifier: "TextCell") as! TextFieldCell
            return textCell
        }
        else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell", for: indexPath) as UITableViewCell
        
            if let item = products?[indexPath.row - 1]{
                cell.textLabel?.text = item.name
                cell.accessoryType = item.checked ? .checkmark : .none
                }
            return cell
            }
    }

    //MARK: - TableView Delegate Methods
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            print("it works")

        }
    
    func loadProducts(){
        products = realm.objects(Product.self)
        self.tableView.reloadData()
    }
    


   //MARK: - TextFieldDelegate Method
    func saveProduct(newProduct: Product){
        do{
            try realm.write {
                realm.add(newProduct)
            }
        }catch{
            print("Error saving context in Product \(error)")
        }
        tableView.reloadData()
            }


    @IBAction func refreshButtonPressed(_ sender: UIBarButtonItem) {
        self.tableView.reloadData()
    }
    
}

我尝试从文本字段添加项目后出现问题。 saveProduct()将项目保存到数据库,调用TableView cellForRowAt,甚至返回所需的值。但是那之后不调用cellForRowAtindexPath()。

我试图创建一个单独的“刷新按钮”,该按钮仅调用reload Data方法,并且效果很好。

提前谢谢!

2 个答案:

答案 0 :(得分:0)

删除这两行,您不需要它! 因为您正在使用tableViewController并覆盖了类委托和数据源方法!

window.onload = ()=>{
  // get all our buttons
  let buttons = document.getElementsByClassName('button-clickers');
  // the event we plan on invoking
  let clickEvent = new Event('click');
  // assign an event handler for each button
  for(let i = 0; i < buttons.length; i++){
    buttons[i].addEventListener('click', function(){
      console.log(`hi, you have triggered ${this.value}'s click event.`);
    });
  }
  // trigger the click event for each button
  for(let i = 0; i < buttons.length; i++){
    buttons[i].dispatchEvent(clickEvent);
    // buttons[i].click(); // This works too.
  }
}

那您的新数据呢?您只能在vieDidLoad上调用一次“ loadProducts()”吗? 在调用tableView.reloadData()之前,将列表发布者添加到您的领域产品中,或调用“ loadProducts()”。

尝试一下。

答案 1 :(得分:0)

发现问题了!

结果表明,在创建单元格时需要在cellForRowAtindexPath()内部分配单元格委托。所以我在这里添加了代码行

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let textCell = tableView.dequeueReusableCell(withIdentifier: "TextCell") as! TextFieldCell
        textCell.delegate = self
        return textCell
    }

并从TextFieldCell中删除了基础代码:

override func awakeFromNib() {
        let vc = ListViewController()
        self.delegate = vc
    }