You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UITableViewCell中复用KPDDropDownMenu解决滚动复用问题

Fixing KPDDropDownMenu Content Residue in Reusable UITableViewCells

Hey, I've dealt with this exact reusable cell state issue with dropdown menus before—let's break down the fixes tailored to your code:

1. Reset Dropdown State in setup (Critical!)

The main problem is that when cells are reused, the old dropdown state (expanded status, leftover items, or stale closures) sticks around. Update your setup method to fully reset the dropdown before applying new data:

func setup(withSearchObject searchObject: SearchObject) {
    // Collapse the dropdown immediately to clear old expanded state
    dropDownOptions.collapseAllOptions(animated: false)
    // Clear any old closure references to prevent wrong section updates
    dropDownOptions.optionsDidAppearedWithHeightClosure = nil
    
    // Now apply the new content
    searchkeyL.text = searchObject.searchKey
    dropDownOptions.items = searchObject.options
}

2. Fix Stale IndexPath in Closures

Your current closure captures the original indexPath from cellForRowAt, but when the cell is reused, that indexPath no longer matches the cell's current position. Instead, get the cell's live indexPath when the closure fires:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let searchObject = searchObjects[indexPath.section]
    let cell = tableView.dequeueReusableCell(withIdentifier: searchObject.viewIdentifier, for: indexPath)
    (cell as! CommonSearch).setup(withSearchObject: searchObject)
    
    if let dropDownCell = cell as? _DropDownTVC {
        dropDownCell.dropDownOptions.optionsDidAppearedWithHeightClosure = { [weak self] optionsHeight in
            guard let self = self,
                  let currentIndexPath = tableView.indexPath(for: dropDownCell) else { return }
            // Use the current, live indexPath instead of the original captured one
            self.searchObjects[currentIndexPath.section].viewHeight += optionsHeight
            tableView.beginUpdates()
            tableView.endUpdates()
        }
        // Bonus: Add a closure for when the dropdown closes to adjust height back
        dropDownCell.dropDownOptions.optionsDidDisappearedWithHeightClosure = { [weak self] optionsHeight in
            guard let self = self,
                  let currentIndexPath = tableView.indexPath(for: dropDownCell) else { return }
            self.searchObjects[currentIndexPath.section].viewHeight -= optionsHeight
            tableView.beginUpdates()
            tableView.endUpdates()
        }
    }
    return cell
}

Notice we use [weak self] to avoid memory leaks, and fetch the cell's current indexPath directly from the tableView when the event triggers.

3. Use prepareForReuse to Clean Up Reusable Cells

Add this to your _DropDownTVC class to ensure all old state is wiped before the cell is reused—this is a standard practice for UITableViewCell reuse:

override func prepareForReuse() {
    super.prepareForReuse()
    // Reset dropdown state
    dropDownOptions.collapseAllOptions(animated: false)
    dropDownOptions.optionsDidAppearedWithHeightClosure = nil
    dropDownOptions.optionsDidDisappearedWithHeightClosure = nil
    // Reset text labels to avoid leftover text
    searchkeyL.text = nil
}

This acts as a safety net, ensuring no old content or callbacks linger when the cell is recycled.

4. Verify Height Adjustment Logic

Make sure your viewHeight property is correctly managing the cell's height—without the close closure I added earlier, your height would keep increasing every time the dropdown opens, leading to weird cell sizing over time. The close callback fixes that by subtracting the dropdown height when it's hidden.

These changes address both the content residue issue (by fully resetting the dropdown on reuse) and the incorrect section updates (by using the cell's live indexPath in closures).

内容的提问来源于stack exchange,提问作者MAHMOUD OMARA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:17:06