如何让数组在UITableView上显示为转换为日期的字符串?

How to get an array displayed on UITableView of dates as strings converted to dates?

提问人:Miguel Carvalho 提问时间:10/6/2023 最后编辑:Miguel Carvalho 更新时间:10/6/2023 访问量:38

问:

我制作了一个自定义单元格,它显示了从实时数据库(Firebase)检索到的字符串的一些重要详细信息。这一切都运行良好,没有任何问题。

我的问题是我需要从每个单元格上的这些文本标签中获取日期(从字符串数组中检索,从数据库中获取),将它们转换为日期,然后计算它是否从该日期过去了 3 天以上,如果是这样,该单元格将突出显示颜色,以便用户可以注意。

我可以将字符串转换为日期,没问题,我在这里的问题是如何从数组中做到这一点,并让单元格知道文本字段上显示的日期早于 3 天。

我想我知道该怎么做,那就是将数组转换为日期,然后在文本标签上显示日期,而不是字符串,然后创建一个条件来查看日期是否早于 3 天,如果是,请突出显示单元格。

我的问题是我不知道如何做到这一点,因为每次我尝试将数组转换为日期时,我都会得到零。

谁能给我一个方向或方向,我对编程有点陌生,第一次使用 TableView 这样做。

更新

这是我的 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
    }

这是从实时数据库中检索数据的代码:

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)")
            }
        }
    }


我的自定义单元配置代码在这里:

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
    }
    
}

Swift UITableView Firebase-实时数据库

评论


答:

1赞 Duncan C 10/6/2023 #1

表视图和集合视图使用数据源。这是一个实现多种方法的对象,这些方法告诉表/集合视图有多少个部分和行,并在询问时提供单元格。

通常,数据源由数组(如果使用分段表/集合视图,则由数组的数组)提供。结构数组效果很好,因为结构可以保存单元格中所有所需内容的属性。

您需要设置一个模型,以便根据需要配置单元。

我建议使用一个结构数组,这些结构体同时包含用于显示的日期字符串和 Date 对象或布尔值,让您决定是否需要突出显示每个单元格。

您可以从填充日期字符串但字段为空的结构数组开始。然后对结构数组执行映射语句,将字段替换为 you compute from the date String(使用 DateFormatter)DateDateDate

除非我们知道您的数据是什么样子,否则我们无法帮助您进行设置。编辑问题以显示当前用于保存单元格数据的数据结构以及一些示例数据。此外,还显示一些示例日期字符串,以及用于将日期字符串转换为 Date 对象的代码。(不要回复评论。将信息添加到原始问题中。

编辑:

我创建了一个示例结构,其中包含日期、字符串属性和可选属性:PersonbirthdayisOver18

struct Person: CustomStringConvertible {
    let name: String
    let birthdayString: String
    var birthday: Date? = nil
    var isOver18: Bool?  = nil
    
    var description: String {
        var description = "Person(\n"
        let birthdayDisplayString = birthday?.description(with: .current) ?? "nil"
        let isOver18String = isOver18.map { $0 ? "true" : "false" } ?? "nil"
        description += "  name: \(name)\n"
        description += "  birthdayString: \(birthdayString)\n"
        description += "  birthday: \(birthdayDisplayString)\n"
        description += "  isOver18: \(isOver18String)\n"
        description += ")"
        return description
    }
}

然后编写示例代码,用名称和日期字符串填充这些对象的数组。然后,我编写了一个函数,将 Person 结构映射到包含其 birthday 和 'isOver18 属性的 Person 结构:PersonDate

class ViewController: UIViewController {

    // Create a DateFormatter
    let formatter: DateFormatter = {
        let aFormatter = DateFormatter()
        aFormatter.dateFormat = "MMM dd, yyyy HH:mm:ss z"
        return aFormatter
    }()

    var people = [Person]()
    
    // A function that takes a Person struct as input and returns another Person with their `birthday` and `isOver18` properties populated.
    func addBirthdayInfo(person: Person) -> Person {
        let today = Calendar.current.startOfDay(for: Date())
        
        var newPerson = person
        newPerson.birthday = formatter.date(from: person.birthdayString)
        if let birthday = newPerson.birthday,
            let date18YearsAgo = Calendar.current.date(byAdding: .year, value: -18, to: today, wrappingComponents: false) {
            newPerson.isOver18 = birthday < date18YearsAgo
        }
        return newPerson
    }
    
    // Create an array of Person with only name and birthdaySring fields poulated
    func createPeople() {
        let secondsIn5Years = Double(60 * 60 * 24 * 365 * 5)
        let secondsIn30Years = secondsIn5Years * 6
        let names = ["John Doe", "Bertrand Russel", "Franz Kafka", "Suzie Creamcheese", "Moon Unit Zappa", "Jose Juarez", "Hans Christian Anderson", "Boutros Boutros-Ghali", "Angela Merkel", "Élisabeth Borne"]
        for name in names {
            // Generate a random birhtdate for this person any time between 5 and 30 years ago.
            let birthdate = Date().addingTimeInterval(Double.random(in: 0-secondsIn30Years..<0-secondsIn5Years))
            let person = Person(name: name, birthdayString: formatter.string(from:birthdate))
            people.append(person)
        }
    }
    
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        createPeople()
        
        // Go though the array of people and replace each struct with a stuct containing `birthday` and `isOver18` properties.
        people = people.map{ addBirthdayInfo(person: $0)}
        for person in people {
            print(person)
        }
    }
}

如果运行该代码,它将创建一个 Person 对象数组,为这些对象分配随机的生日字符串,然后执行另一次传递来填充每个 Person 的 and 属性。PersonbirthdayDateisOver18Bool

这应该让你了解如何编写代码。

评论

0赞 Miguel Carvalho 10/6/2023
非常感谢您的回答。我在此处添加的代码会有所帮助吗?
0赞 Duncan C 10/6/2023
这是一个开始。您如何配置您的细胞?(添加方法的代码。一个建议:不要设置多个数组,每个数组都包含一个单独的数据元素。这条路通向疯狂。相反,创建一个结构数组,其中结构包含显示单元格所需的所有数据元素。configure()
0赞 Miguel Carvalho 10/6/2023
我已使用请求的代码更新了我的问题。我尝试过做一个数组结构,但我在实现它时遇到了问题。我到了迷茫的地步,以至于我决定分别做这四个。
0赞 Duncan C 10/6/2023
因此,问题的重点是如何根据该条目的日期字符串选择单元格,但您没有显示任何尝试实现该逻辑的代码。我们如何帮助您调试未显示的代码?我还要求您展示一些示例数据,包括日期字符串和用于解析该日期字符串的代码。(如果提问者没有提供完整的问题描述,并且不得不一次又一次地返回并询问更多信息,则尝试回答问题令人沮丧。
0赞 Miguel Carvalho 10/6/2023
好吧,对不起,我无意让你感到沮丧。1. 英语是我的第二语言,我会尽力解释我的问题;2. 我还没有任何代码,因为我使用的代码根本不起作用,所以我放弃了,来这里寻求帮助。目前,我尚未将从数据库获取的日期字符串转换为我的代码。如果我说的话不明确,我真的很抱歉。如果有您需要帮助我的所有内容的清单,请告诉我,我将提供我必须实现的所有数据和代码。