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

完成个人目标后更新并重新加载UITableView问题求助

解决UITableViewCell完成目标后无法更新的问题

看起来你的问题核心是两个点:一是完成目标后completionView的显示逻辑和预期不符,二是UITableView没有正确更新cell状态。我帮你梳理下问题并给出具体修复方案:

1. 首先修复cell配置中的错误覆盖问题

在cellForRowAt方法里,你调用cell.configureCell(goal: goal)之后,又手动把goalDescriptionLbl2设为空,这直接覆盖了配置好的内容,先把这行删掉:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "goalCell") as? GoalCell else { return UITableViewCell() }
    let goal = goals[indexPath.row]
    cell.configureCell(goal: goal)
    // 删掉这行,它会覆盖configureCell里的设置
    // cell.goalDescriptionLbl2?.text = ""
    return cell
}

2. 调整completionView的显示逻辑(符合你的需求)

你当前的代码是目标完成时显示completionView,但你希望完成后移除它,所以把configureCell里的条件反过来:

func configureCell(goal: Goal) {
    self.goalDescriptionLbl.text = goal.goalDescription
    self.goalDescriptionLbl2.text = goal.goalDescription2
    self.goalProgressLbl.text = String(describing: goal.goalProgress)
    // 修改条件:完成目标时隐藏completionView
    if goal.goalProgress == goal.goalCompletion {
        self.completionView.isHidden = true
    } else {
        self.completionView.isHidden = false
    }
}

3. 修复数据源更新与UI刷新的顺序

在左滑操作的handler里,你当前的顺序是先刷新cell再更新数据源,这会导致UI使用旧数据。应该先更新Core Data并重新获取数据源,再刷新对应的cell:

func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let addAction = UIContextualAction(style: .normal, title: "", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
        self.setProgress(atIndexPath: indexPath)
        // 先更新数据源,再刷新对应行
        self.fetch { [weak self] success in
            guard let self = self else { return }
            if success {
                tableView.reloadRows(at: [indexPath], with: .automatic)
            }
        }
        success(true)
    })
    addAction.image = UIImage(named: "Add1")
    addAction.backgroundColor = #colorLiteral(red: 0.9529411765, green: 0.9607843137, blue: 0.9803921569, alpha: 1)
    return UISwipeActionsConfiguration(actions: [addAction])
}

4. 优化setProgress方法的完整性

当目标已经完成时,你的方法直接return,但可以补充日志或后续处理,确保流程完整:

func setProgress(atIndexPath indexPath: IndexPath) {
    guard let managedContext = appDelegate?.persistentContainer.viewContext else { return }
    let chosenGoal = goals[indexPath.row]
    if chosenGoal.goalProgress < chosenGoal.goalCompletion {
        chosenGoal.goalProgress = chosenGoal.goalProgress + 1
        do {
            try managedContext.save()
            print("Successfully set progress")
        } catch {
            debugPrint("Could not set progress: \(error.localizedDescription)")
        }
    } else {
        print("Goal already completed, no progress added")
        // 这里可以添加完成后的额外逻辑,比如标记目标为已归档等
    }
}

为什么之前无法更新?

  • cellForRowAt里的额外赋值覆盖了cell的配置,导致部分内容显示异常。
  • UI刷新在数据源更新之前,导致cell使用旧的目标状态渲染。
  • completionView的显示逻辑和你的需求完全相反,所以完成目标后反而显示了不需要的视图。

这样调整后,当你左滑增加进度到完成值时,cell会正确隐藏completionView,并且UITableView会及时更新状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 20:23:00