为什么折叠/可扩展的iOS UITableView行在交互时会消失?

时间:2017-06-02 12:48:29

标签: ios swift uitableview

我是iOS开发的新手,我刚刚实现了一个简单的可扩展部分UITableView。我无法理解为什么有些行会消失,有时在点击节标题时重新计算行高度时会改变位置。我查看了有关此主题的所有已回答的问题,但未能找到正确的解决方案。

以下是一个场景:

  1. 启动应用程序:
  2. state-1

    1. 点击标题标题:
      • 部分展开
      • 所有其他标题消失
    2. state-2

      1. 再次点按
        • 部分崩溃
        • 标题继续为空白
      2. state-3

        1. 滚动到底部并返回顶部
          • 标题的位置已更改
        2. state-4

          1. 滚动到底部并再次返回顶部
            • 标题的位置再次更改,部分单元格仍为空白
          2. state-5

            我已经尝试过的事情:

            • 更新块中包装reloadRowsAtIndexPaths (beginUpdates()和endUpdates())
            • 使用动画设置为.none
            • 的reloadRowsAtIndexPaths
            • 完全删除reloadRowsAtIndexPaths,同时保持更新阻止
            • 使用reloadData()而不是实际有效,但我失去了动画

            代码:

            • Here是项目存储库的链接。

2 个答案:

答案 0 :(得分:0)

  • 您正在使用标题的单元格。你不应该这样做,你需要一个常规的UIView,或者至少一个没有像那样出列的单元格。当你运行它时会发出一些警告。通常只需要在视图中创建一个独立的xib,然后在头类中使用这样的静态方法。确保将出口连接到视图本身,而不是所有者:

    procedure TMyComp.Execute_FormShowModal;
    var
      frm: TForm;
    begin
      frm := TFormClass(FForm.ClassType).Create(FParentForm);
    
      { to acess the class specific members you will have to typecast to a
        specific class (or use RTTI, which is even more difficult) }
      if frm is TMyForm then
        TMyForm(frm).BtnOK.Enabled := False;
    
      frm.ShowModal;
      frm.Free;
    end;
    
  • 您正在重新加载增长部分中的单元格,但是当您更改已增长的部分时,您需要至少重新加载前一部分,以便对其单元格的高度进行更改。在两种情况下,您都可以按索引而不是单个行重新加载部分

答案 1 :(得分:0)

好的,你问我,我正在改变你的答案。

import UIKit

class MyTableViewController: UITableViewController {
    let rows = 2
    var categories = [Int](repeating: 0, count: 10)

    struct Constants {
        static let noSelectedSection = -1
    }

    var selectedSection: Int = Constants.noSelectedSection

    func selectedChanged(to selected: Int?) {
        let oldIndex = selectedSection;
        if let s = selected {
            if selectedSection != s {
                selectedSection = s
            } else {
                selectedSection = Constants.noSelectedSection
            }

            tableView.beginUpdates()
            if(oldIndex != -1){
                tableView.reloadSections([oldIndex,s], with: .automatic)

            }else{
                tableView.reloadSections([s], with: .automatic)
            }
            tableView.endUpdates()

        }
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return categories.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("reloading section \(section)")
        return (selectedSection == section) ? rows : 0;//rows
    }

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return tableView.rowHeight
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return tableView.rowHeight

    }

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Header")
        if let categoryCell = cell as? MyTableViewCell {
            categoryCell.category = section + 1
            let recognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture))
            recognizer.numberOfTapsRequired = 1
            recognizer.numberOfTouchesRequired = 1
            categoryCell.contentView.tag = section;
            categoryCell.contentView.addGestureRecognizer(recognizer)

        }
        return cell?.contentView
    }

    func handleTapGesture(recognizer: UITapGestureRecognizer) {
        if let sindex = recognizer.view?.tag {
            selectedChanged(to: sindex)
        }
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Body", for: indexPath)
        if let label = cell.viewWithTag(1) as? UILabel {
            label.text = "Body \(indexPath.section + 1) - \(indexPath.row + 1)"
        }
        return cell
    }

}

正如您现在所看到的,我只是重新加载特定部分而不是重新加载整个表。

另外,我已经从手机和手机中移除了手势识别器。把它放进主控制器。