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

Swift4中点击按钮重载指定TableView分区失效问题求助

问题分析与解决

首先看你代码里的几个关键问题,导致了所有分区都被“刷新”的现象:

  • 全局变量onReload的逻辑缺陷:你用一个全局布尔值控制所有分区的行高,只要它变为true,所有分区的行高都会从0切换到40。哪怕你只刷新了分区0,其他分区的行高也会因为这个全局变量的变化而改变,看起来就像所有分区都被重载了。
  • 硬编码刷新分区0:在tapOnHeaderView里你写死了let sectionToReload = 0,不管点击哪个表头按钮,都只会刷新分区0,完全违背了你“重载指定分区”的需求,应该用按钮的tag来获取目标分区。
  • 表头按钮重复添加:每次viewForHeaderInSection被调用时,你都会给表头添加一个新的UIButton,多次刷新表头后,同一个表头会叠加多个按钮,可能导致点击事件混乱。

修正后的代码实现

第一步:替换全局变量为分区展开状态数组

把全局的onReload改成数组,用来单独记录每个分区的展开/折叠状态:

// 记录每个分区的展开状态,默认全部折叠
var sectionExpanded: [Bool] = []

override func viewDidLoad() {
    super.viewDidLoad()
    // 假设array是你的分区数据源,初始化时根据分区数设置初始状态
    sectionExpanded = Array(repeating: false, count: array.count)
}

第二步:修正表头视图的点击事件逻辑

建议用手势识别器替代重复添加按钮的方式,避免叠加问题:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
    let headerView = tableView.dequeueReusableCell(withIdentifier: "reuseCell") as! CustomCell 
    let dict = array[section] as! [String:Any]
    let firstKey = Array(dict.keys)[0] 
    headerView.categoryLabel.text = firstKey 
    headerView.categoryLabel.textColor = .black 

    // 先移除之前的手势,避免重复添加
    headerView.gestureRecognizers?.forEach { gesture in
        if gesture is UITapGestureRecognizer {
            headerView.removeGestureRecognizer(gesture)
        }
    }

    // 添加点击手势,绑定当前分区
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapOnHeaderView(_:)))
    headerView.tag = section
    headerView.addGestureRecognizer(tapGesture)

    return headerView
}

第三步:修正点击事件与分区刷新逻辑

点击表头时,切换对应分区的展开状态,然后只刷新该分区:

@objc func tapOnHeaderView(_ gesture: UITapGestureRecognizer){ 
    let section = gesture.view?.tag ?? 0
    // 切换当前分区的展开状态
    sectionExpanded[section] = !sectionExpanded[section]
    // 仅刷新指定分区
    let indexSet = IndexSet(integer: section)
    tableView.reloadSections(indexSet, with: .automatic)
}

第四步:修正行高计算逻辑

根据对应分区的独立状态返回行高:

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        // 仅根据当前分区的展开状态决定行高
        return sectionExpanded[indexPath.section] ? 40 : 0
    }
}

这样修改后,点击某个分区的表头,只会切换该分区的展开状态并刷新这个分区,其他分区的状态不会受到影响,完美实现你想要的“重载指定分区”的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:16:30