swift - 如何在 UITableView 中有条件地分割数据模型?

标签 swift models sections custom-sections

我有一个模型对象以 JSON 格式从 Firebase 返回。

{
    "id": 1,
    "name": "Jon Doe",
    "time": ["1525592246"]
},
{
    "id": 2,
    "name": "Jane Doe",
    "time": ["1525592266"]
},

我想根据以下内容将这些对象组织成 UITableView 中的部分:

enum DiarySectionType {
    case Today
    case Tomorrow
    case ThisWeek
    case ThisMonth
    case Later
}

即如果“时间”是今天,它将位于 UITableView 的今天部分

解决这个问题的最佳方法是什么?我想过为每个单独的数组。但不要认为那是要走的路。

一如既往地感谢任何帮助。

最佳答案

First you need helper extension for your Date

extension Date {

    public func component(_ component: Calendar.Component) -> Int {
        let calendar = Calendar.autoupdatingCurrent
        return calendar.component(component, from: self)
    }

    public var isToday: Bool {
        let calendar = Calendar.autoupdatingCurrent
        return calendar.isDateInToday(self)
    }

    public var isTomorrow: Bool {
        let calendar = Calendar.autoupdatingCurrent
        return calendar.isDateInTomorrow(self)
    }

    public var isThisWeek: Bool {
        return isInSameWeek(date: Date())
    }
    public var isThisMonth: Bool {
        return isInSameMonth(date: Date())
    }
    public var islater: Bool {
       return isInSameMonth(date: Date()) ? false : true
    }

}
extension Date {
    func isInSameWeek(date: Date) -> Bool {
        return Calendar.current.isDate(self, equalTo: date, toGranularity: .weekOfYear)
    }
    func isInSameMonth(date: Date) -> Bool {
        return Calendar.current.isDate(self, equalTo: date, toGranularity: .month)
    }
}

Then your Enum

enum DiarySectionType:Int{
    case Today
    case Tomorrow
    case ThisWeek
    case ThisMonth
    case Later
    case count // use for number of section
    init (with date:Date){

        if date.isToday {
            self = .Today
        }else if date.isTomorrow{
             self = .Tomorrow
        }else if date.isThisWeek{
            self = .ThisWeek
        }else if date.isThisMonth{
             self = .ThisMonth
        }else{
           self = .Later
        }
    }
}

Your data Formalize as you need

struct Item{
    var id : Int
    var name : String
    var time : Double
    init(id:Int, name:String,time:Double) {

        self.id = id
        self.name = name
        self.time = time
    }
}

// Controller

  class  ViewController: UIViewController{

          var data = [Item]() // your data before sections
          var dataWork = [DiarySectionType: [Item]]() // date After sections

        override func viewDidLoad() {
            super.viewDidLoad()

            self.sortData()

          }

   // When generating sorted table data we can easily use our TableSection to make look up simple and easy to read.
        func sortData() {
            dataWork[.Today] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time))  == .Today })
            dataWork[.Tomorrow] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time))  == .Tomorrow })
            dataWork[.ThisWeek] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time))  == .ThisWeek })
            dataWork[.ThisMonth] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time))  == .ThisMonth })
            dataWork[.Later] = data.filter({ DiarySectionType.init(with: Date.init(timeIntervalSince1970: $0.time))  == .Later })
        }
    }




extension ViewController: UITableViewDataSource, UITableViewDelegate {

    // As long as `count` is the last case in our TableSection enum,
    // this method will always be dynamically correct no mater how many table sections we add or remove.
    func numberOfSections(in tableView: UITableView) -> Int {
        return DiarySectionType.count.rawValue
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Using Swift's optional lookup we first check if there is a valid section of table.
        // Then we check that for the section there is data that goes with.
        if let tableSection = DiarySectionType(rawValue: section), let data = dataWork[tableSection] {
            return data.count
        }
        return 0
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        var title : String = ""
        if let tableSection = DiarySectionType(rawValue: section) {
            switch tableSection {
            case .Today:
                title = "Today"
            case .Tomorrow:
                title = "Tomorrow"
            case .ThisMonth:
                title = "ThisMonth"
            case .ThisWeek:
                title = "ThisWeek"
            case .Later:
                title = "Later"
            default:
                title = ""
            }
        }

        return title
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        // Similar to above, first check if there is a valid section of table.
        // Then we check that for the section there is a row.
        if let tableSection = DiarySectionType(rawValue: indexPath.section), let item = dataWork[tableSection]?[indexPath.row] {
          // use item item

        }
        return cell
    }

}

关于swift - 如何在 UITableView 中有条件地分割数据模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50197382/

相关文章:

html - 调整浏览器窗口大小时如何防止部分重叠?

ios - 使用第二个 UIViewController 启动 ViewPagerController

ios - 快速将 uiimageview 保存到 tableview?

django - 在 admin 中显示通过 'through' 定义的 m2m 字段

javascript - AngularJS 两个具有共享模型的 Controller , Controller 2 没有看到模型的更改

ios - 使用部分时继续详细了解 UItableView

arrays - 在 Swift 中转换 [UInt32] -> [UInt8] -> [[UInt8]]

ios - 从委托(delegate)调用时 UIView.animateWithDuration 不起作用?

ruby-on-rails - Rails 的问题 has_many 关系

python-sphinx - 如何链接到狮身人面像toctree中的页面部分