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

如何将字符串日期数组转成日期并在UITableView高亮超3天单元格

问题描述

我已经做好自定义UITableViewCell,用来展示从Firebase Realtime Database获取的关键字符串信息,这部分功能正常。现在需要实现:获取每个单元格文本标签里的日期(来自数据库的字符串数组),转成日期类型后判断是否已超过3天,若是则高亮单元格提醒用户。

我能单独把字符串转成日期,但不知道怎么批量处理数组,也不清楚怎么让单元格知晓对应的日期已超3天。我的思路是把数组转成日期后再显示到文本标签,再加条件判断,超3天就高亮,但转换数组时一直得到nil值。我是编程新手,第一次用UITableView,求指导。


更新:相关代码

UITableView 代理方法代码

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = UITableViewCell()
    var projects = self.projectsArray[indexPath.row]
    var dates = self.projectsDateArray[indexPath.row]
    var statuses = self.projectsStatusArray[indexPath.row]
    var users = self.projectsUserArray[indexPath.row]
    
    cell.textLabel?.text = projects
    
    if indexPath.row > 0 {
        let customCell = self.projectsTableView.dequeueReusableCell(withIdentifier: OrderManagementCell.identifier) as! OrderManagementCell
        customCell.configure(with: projects, date: dates, status: statuses, user: users)
        return customCell
    }
    
    return cell
}

Firebase Realtime Database 数据获取代码

func getTableViewData() {
    let ref = databaseRef.child("User_Information").child("\(dataName)").child("Projects")
    
    ref.observe(.value) { (snapshot) in
        for details in snapshot.children {
            let snap = details as! DataSnapshot
            let project = snap.value as! [String: Any]
            let date = project["Date"] as! String
            let status = project["Status"] as! String
            let user = project["User"] as! String
            self.projectsDateArray.append(date)
            self.projectsStatusArray.append(status)
            self.projectsUserArray.append(user)
            //print("\(date) \(status) \(user)")
        }
    }
}

自定义Cell 代码

import UIKit

class OrderManagementCell: UITableViewCell {
    
    static let identifier = "OrderManagementCell"
    static func nib() -> UINib {
        return UINib(nibName: "OrderManagementCell", bundle: nil)
    }
    
    public func configure(with title: String, date: String, status: String, user: String) {
        cellTitle.text = title
        cellDate.text = date
        cellStatus.text = status
        cellUser.text = user
    }
    
    @IBOutlet var cellTitle: UILabel!
    @IBOutlet var cellDate: UILabel!
    @IBOutlet var cellStatus: UILabel!
    @IBOutlet var cellUser: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
    
}

解决方案

1. 先解决日期转换nil的核心问题

你转换数组时得到nil,大概率是日期格式不匹配。先定义一个全局的日期格式化工具,确保和数据库存储的日期字符串格式完全一致:

// 在ViewController里定义(或单独工具类)
let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd" // 替换成你数据库里的日期格式,比如"MM/dd/yyyy"或"yyyy-MM-dd HH:mm"
    formatter.locale = Locale(identifier: "en_US_POSIX")
    return formatter
}()

2. 用模型类替代多数组存储(避免索引混乱)

现在用多个数组存数据容易出错,建议创建Project模型统一管理:

struct Project {
    let title: String
    let dateString: String
    let status: String
    let user: String
    
    // 直接计算转换后的日期,方便后续判断
    var date: Date? {
        return dateFormatter.date(from: dateString)
    }
}

然后把原来的多个数组替换成一个:

var projects: [Project] = []

修改数据获取代码,同时记得刷新表格:

func getTableViewData() {
    let ref = databaseRef.child("User_Information").child("\(dataName)").child("Projects")
    
    ref.observe(.value) { (snapshot) in
        self.projects.removeAll() // 清空旧数据
        for details in snapshot.children {
            let snap = details as! DataSnapshot
            let projectDict = snap.value as! [String: Any]
            // 假设项目标题存在snap.key里,或者从dict取"Title"字段,根据你的数据库结构调整
            guard let title = snap.key as String? else { continue }
            let date = projectDict["Date"] as! String
            let status = projectDict["Status"] as! String
            let user = projectDict["User"] as! String
            
            let project = Project(title: title, dateString: date, status: status, user: user)
            self.projects.append(project)
        }
        self.projectsTableView.reloadData() // 必须刷新表格才会显示新数据
    }
}

3. 修改TableView代理方法,实现日期判断与单元格高亮

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let project = projects[indexPath.row]
    // 直接复用自定义Cell,移除原来indexPath.row>0的不合理判断
    let customCell = tableView.dequeueReusableCell(withIdentifier: OrderManagementCell.identifier, for: indexPath) as! OrderManagementCell
    customCell.configure(with: project.title, date: project.dateString, status: project.status, user: project.user)
    
    // 判断日期是否超过3天
    if let projectDate = project.date {
        let threeDaysAgo = Calendar.current.date(byAdding: .day, value: -3, to: Date())!
        if projectDate < threeDaysAgo {
            // 高亮样式:比如背景色变黄,日期标签变红
            customCell.backgroundColor = UIColor.systemYellow.withAlphaComponent(0.3)
            customCell.cellDate.textColor = .red
        } else {
            // 恢复默认样式
            customCell.backgroundColor = .clear
            customCell.cellDate.textColor = .label
        }
    } else {
        // 日期转换失败时的默认样式
        customCell.backgroundColor = .clear
        customCell.cellDate.textColor = .label
    }
    
    return customCell
}

4. 修复Cell复用的样式残留问题

为了避免Cell复用时高亮样式残留,在自定义Cell里添加重置逻辑:

class OrderManagementCell: UITableViewCell {
    // ... 原有代码 ...
    
    override func prepareForReuse() {
        super.prepareForReuse()
        // 重置所有可能被修改的样式
        backgroundColor = .clear
        cellDate.textColor = .label
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:25:19