添加更多单元格后,某些表格视图单元格变得不可见。为什么呢?

时间:2016-07-11 09:43:44

标签: ios swift uitableview

我正在使用this post中提到的技术的变体来动态添加和删除表格视图单元格。

最初,表格视图单元格如下所示:

enter image description here

然后,我在第1部分添加了一个新单元格。第1部分是“结果”部分上方的部分。所以我希望新单元格出现在名为“h”的单元格下方。但不是!它变成了这个!

enter image description here

新细胞添加在第2部分(“结果”部分)中,并添加到名为“b”的细胞下方。更令人惊讶的是,第2节中的第二个单元格已经消失了!

以下是我添加单元格的方法:

我在这里有一组单元格:

var cells: [[UITableViewCell]] = [[], [], []]

数组中的每个子数组表示一个部分。在viewDidLoad中,我通过调用:

将一些单元格添加到0到2节
addCellToSection(1, cell: someCell)

addCellToSection定义为

func addCellToSection(section: Int, cell: UITableViewCell) {
    cells[section].append(cell)
    tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: cells[section].endIndex - 1, inSection: section)], withRowAnimation: .Top)
}

表视图数据源方法的定义方式与上述帖子相同。

我在添加单元格时尝试打印每个部分中的单元格数量:

print("no. of rows in section 1: \(self.tableView(tableView, numberOfRowsInSection: 1))")
print("no. of rows in section 2: \(self.tableView(tableView, numberOfRowsInSection: 2))")

打印的值是一致的,即当我添加一个新的单元格时,没有。行增加1.但奇怪的是它一直将行放在错误的位置。

额外信息:我如何创建单元格:

我首先从原型细胞中取出细胞。然后,我致电viewWithTag以获取单元格中的文本字段,并将其添加到[(UITextField, UITextField)]。不知道这是否重要。

1 个答案:

答案 0 :(得分:1)

好的,首先,你应该从不在一些自定义集合中存储UITableView单元格。这是并且应该由iOS完成,而不是你。

用于填充单元格的数据存储在我认为的某个模型中?

您的tableView应使用以下任一方式注册单元格:  func registerClass(cellClass: AnyClass?, forCellReuseIdentifier identifier: String)

func registerNib(nib: UINib?, forCellReuseIdentifier identifier: String)

或在Xib / Storyboard中使用Prototype单元格。

我推荐此设置或类似设置:

class MyModel {
        /* holds data displayed in cell */
        var name: String?
        var formula: String?
        init(name: String, formula: String) {
            self.name = name
            self.formula = formula
        }
    }

class MyCustomCell: UITableViewCell, UITextFieldDelegate {
    static var nibName = "MyCustomCell"

    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var formulaTextField: UITextField!
    weak var model: MyModel?

    override func awakeFromNib() {
        super.awakeFromNib()
        nameTextField.delegate = self
        formulaTextField.delegate = self
    }

    func updateWithModel(model: MyModel) {
        /* update labels, images etc in this cell with data from model */
        nameTextField.text = model.name
        formulaTextField.text = model.formula
        self.model = model
    }

    /* This code only works if MyModel is a class, because classes uses reference type, and the value
     of the name and formula properies are changed in the model stored in the dictionary */
    func textFieldShouldEndEditing(textField: UITextField) -> Bool {
        let newText = textField.text
        switch textField {
        case nameTextField:
            model?.name = newText
        case formulaTextField:
            model?.formula = newText
        default:
            print("Needed by compiler..")
        }
    }
}

class MyController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableVieW: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        /* This is not needed if you are using prototype cells in the Xib or Storyboard. 
         Convenient to use nib name as cell identifier */
        tableVieW.registerNib(UINib(nibName: MyCustomCell.nibName, bundle: nil), forCellReuseIdentifier: MyCustomCell.nibName)
        tableVieW.delegate = self
        tableVieW.dataSource = self
    }

    private var dictionaryWithModelsForSection: Dictionary<Int, [MyModel]>!

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        let sectionCount = dictionaryWithModelsForSection.keys.count
        return sectionCount
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let models: [MyModel] = modelsForSection(section) else {
            return 0
        }
        let rowCount = models.count
        return rowCount
    }

    private func modelsForSection(section: Int) -> [MyModel]? {
        guard section < dictionaryWithModelsForSection.count else {
            return nil
        }
        let models = dictionaryWithModelsForSection[section]
        return models
    }

    private func modelAtIndexPath(indexPath: NSIndexPath) -> MyModel? {
        guard let models = modelsForSection(indexPath.section) where models.count > indexPath.row else {
            return nil
        }
        let model = models[indexPath.row]
        return model
    }


    func addRowAtIndexPath(indexPath: NSIndexPath, withModel model: MyModel) {
        add(model: model, atIndexPath: indexPath)
        tableVieW.insertRowsAtIndexPaths([indexPath], withRowAnimation: .None)
    }

    private func add(model model: MyModel, atIndexPath indexPath: NSIndexPath) {
        guard var models = modelsForSection(indexPath.section) where indexPath.row <= models.count else { return }
        models.insert(model, atIndex: indexPath.row)
        dictionaryWithModelsForSection[indexPath.section] = models
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(MyCustomCell.nibName, forIndexPath: indexPath)
        return cell
    }

    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        guard let
            cell = cell as? MyCustomCell,
            model = modelAtIndexPath(indexPath) else { return }
        cell.updateWithModel(model)
    }
}

如果你想插入一个单元格,你可以使用我在上面的MyController中编写的方法addRowAtIndexPath:withModel,你需要从某个函数调用它来创建相应的模型......