首页 > 解决方案 > 无效更新:尝试展开和折叠 UITableView 部分时,第 0 部分中的行数无效

问题描述

在调试时,我发现在我的 numberOfRowInSection 中它总是返回计数并跳过if !DealsDataService.instance.getKellysDeals()[section].isExpanded导致以下错误的条件,因为它不会返回 0。

是否有任何理由会跳过该条件?

错误: 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:第 0 节中的行数无效。更新 (2) 后现有节中包含的行数必须等于包含的行数在更新 (2) 之前的该部分中,加上或减去从该部分插入或删除的行数(0 插入,2 删除),加上或减去移入或移出该部分的行数(0 移入, 0 搬出)。

处理 tableview 以及展开和折叠部分的 ViewController

@IBOutlet weak var daysTable: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()


    daysTable.dataSource = self
    daysTable.delegate = self 
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{

    let view = UIView()
    view.backgroundColor = .black

    let headerLabel = UILabel()
    let button = UIButton(type: .system)

    let headerList = DaysService.instance.getHeader()
    headerLabel.textColor = .yellow
    headerLabel.font = UIFont.boldSystemFont(ofSize: 20)
    headerLabel.backgroundColor = .black
    headerLabel.text = headerList[section]

    button.setTitle("Close", for: .normal)
    button.setTitleColor(.yellow, for: .normal)
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
    button.addTarget(self, action: #selector(handleOpenClose), for: .touchUpInside)
    button.tag = section

    headerLabel.frame = CGRect(x: 5, y: 7.5, width: 150, height: 25)
    button.frame = CGRect(x: 150, y: 7.5, width: 150, height: 25)


    view.addSubview(headerLabel)
    view.addSubview(button)

    return view
}

@objc func handleOpenClose(button: UIButton)
{
    print("trying to expand....")
    let section = button.tag
    var dealsArray = DealsDataService.instance.getKellysDeals()

    var indexPaths = [IndexPath]()

    for deals in dealsArray[section].deals.indices
    {
        print(0, deals)

        let indexPath = IndexPath(row: deals, section: section)
        indexPaths.append(indexPath)
    }

    let isExpanded = dealsArray[section].isExpanded
    dealsArray[section].isExpanded = !isExpanded

    button.setTitle(isExpanded ? "Open" : "Close", for: .normal)

    //still having problem expanding and closing

    if isExpanded
    {
        dealsArray[section].deals.removeAll()
        daysTable.deleteRows(at: indexPaths, with: .fade)
    }
    else
    {
        self.daysTable.insertRows(at: indexPaths, with: .fade)
    }

}

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

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if !DealsDataService.instance.getKellysDeals()[section].isExpanded 
    {
        return 0
    }
    return DealsDataService.instance.getKellysDeals()[section].deals.count

}

func numberOfSections(in tableView: UITableView) -> Int {
    return DealsDataService.instance.getKellysDeals().count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "DaysCell", for: indexPath)
    let deals = DealsDataService.instance.getKellysDeals()[indexPath.section].deals[indexPath.row]
    cell.textLabel?.text = deals
    return cell

}

返回交易数组的数据服务:

static let instance = DealsDataService()
private(set) public var barNames = [Bars]()

public var kellysDeals = [

    ExpandableDeals(isExpanded: true, deals:["$2 Bud Lights", "$1 Tacos"]),//Monday
    ExpandableDeals(isExpanded: true, deals:["$2 Budweiser","$2 Burgers"]),//Tuesday
    ExpandableDeals(isExpanded: true, deals:["$3 Drafts","50 cent wings"]),//Wednesday
    ExpandableDeals(isExpanded: true, deals:["$8 Coors pitchers","$5 Sandwiches"]),//Thursday
    ExpandableDeals(isExpanded: true, deals:["No Deal"]),//Friday
    ExpandableDeals(isExpanded: true, deals:["No Deal"]),//Saturday
    ExpandableDeals(isExpanded: true, deals:["No Deal"])//Sunday
]

func getKellysDeals() -> [ExpandableDeals]
{
    return kellysDeals
}

}

标签: iosswiftuitableview

解决方案


在 handleOpenClose 中,当我应该声明一个全局数组变量然后在我的 handleOpenClose 函数中使用它时,我正在调用 DataService。

var barDeals: [ExpandableDeals] = []

@IBOutlet weak var daysTable: UITableView!

override func viewDidLoad()
{
    super.viewDidLoad()

    daysTable.dataSource = self
    daysTable.delegate = self

}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{

    let view = UIView()
    view.backgroundColor = .black

    let headerLabel = UILabel()
    let button = UIButton(type: .system)

    let headerList = DaysService.instance.getHeader()
    headerLabel.textColor = .white
    headerLabel.font = UIFont.boldSystemFont(ofSize: 20)
    headerLabel.text = headerList[section]

    button.setTitle("Open", for: .normal)
    button.setTitleColor(.white, for: .normal)
    button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
    button.addTarget(self, action: #selector(handleOpenClose), for: .touchUpInside)
    button.tag = section

    headerLabel.frame = CGRect(x: 5, y: 7.5, width: 150, height: 25)
    button.frame = CGRect(x: 150, y: 7.5, width: 150, height: 25)


    view.addSubview(headerLabel)
    view.addSubview(button)

    return view
}

@objc func handleOpenClose(button: UIButton)
{
    let section = button.tag

    self.daysTable.beginUpdates()
    var indexPaths = [IndexPath]()

    for deals in self.barDeals[section].deals.indices
    {
        let indexPath = IndexPath(row: deals, section: section)
        indexPaths.append(indexPath)
    }

    let isExpanded = self.barDeals[section].isExpanded
    self.barDeals[section].isExpanded = !isExpanded

    button.setTitle(!isExpanded ? "Close" : "Open", for: .normal)

    if isExpanded
    {
        daysTable.deleteRows(at: indexPaths, with: .fade)
    }
    else
    {
        daysTable.insertRows(at: indexPaths, with: .fade)
    }

    self.daysTable.endUpdates()

}

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

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if self.barDeals[section].isExpanded == false
    {
        return 0
    }
    return self.barDeals[section].deals.count
}

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

推荐阅读