iOS:带有日期的数组中的 UICollectionView 部分
iOS: UICollectionView sections from array with dates
我有 array
个 Person
。 Person object 之间有许多字段 inscriptionDate
(a timestamp
)。我必须从这个 array
创建一个 collectionView
但使用 sections
。每个部分都有一个 header 即 inscriptionDate
作为具有此格式 dd/mm/yyyy
的日期。我必须按 inscriptionDate
对 array
进行排序,但没有时间(仅格式 dd/mm/yyyy
),以便在 collectionView
中加载数据(考虑到这些部分)。我从另一个问题中发现了这个solution。但是在执行此操作之前如何对 array
进行排序?我该如何使用它:
order = NSCalendar.currentCalendar().compareDate(now, toDate: olderDate,
toUnitGranularity: .Day)
就我而言?
假设您的 inscriptionDate
是 Date
,您为什么不能对其进行排序?因为 Date
符合 Comparable
你所需要的只是
let sortedByDate = persons.sorted { [=10=].inscriptionDate < .inscriptionDate }
首先,您需要在排序前清理时间戳。您可以使用 Calendar
和 Date
扩展名来做到这一点:
extension Date {
func noTime() -> Date! {
let components = Calendar.current.dateComponents([.day, .month, .year], from: self)
return Calendar.current.date(from: components)
}
}
然后你只需要按日期排序你的数组而不用时间:
let sortedByDate = persons.sorted { [=11=].inscriptionDate.noTime() < .inscriptionDate.noTime() }
注意。 注意 Calendar
的 compareDate
函数,因为它只比较特定的组件。如果在此示例中: NSCalendar.currentCalendar().compareDate(now, toDate: olderDate, toUnitGranularity: .Day)
不同月份的日期相同,则比较结果将显示日期相等。
我为你写了一个代码我觉得这个代码对你有用。
//
// ViewController.swift
// sortData
//
// Created by Bijender singh on 26/01/18.
// Copyright © 2018 Bijender singh. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(_ animated: Bool) {
let myDataArray = NSMutableArray()
var myDataDic = NSMutableDictionary()
myDataDic.setValue("Bijender", forKey: "name")
myDataDic.setValue("1516965600", forKey: "date")
myDataArray.add(myDataDic)
myDataDic = NSMutableDictionary()
myDataDic.setValue("ben", forKey: "name")
myDataDic.setValue("1516965540", forKey: "date")
myDataArray.add(myDataDic)
myDataDic = NSMutableDictionary()
myDataDic.setValue("Deke", forKey: "name")
myDataDic.setValue("1516842180", forKey: "date")
myDataArray.add(myDataDic)
myDataDic = NSMutableDictionary()
myDataDic.setValue("Veer", forKey: "name")
myDataDic.setValue("1516842000", forKey: "date")
myDataArray.add(myDataDic)
myDataDic = NSMutableDictionary()
myDataDic.setValue("Ashfaq", forKey: "name")
myDataDic.setValue("1515981900", forKey: "date")
myDataArray.add(myDataDic)
print(myDataArray)
let sortedArray = self.sortDataWithDate(arrayData: myDataArray)
// sortedArray contane array which contan same date array
// you can use it according to you
// sortedArray.count is total diffrent dates in your array
// and (sortedArray.count[i] as! NSArray).count give you count of data of that date (0 < i < sortedArray.count)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func sortDataWithDate(arrayData : NSArray) -> NSArray {
// var chat: [ChatMessage]!
let returnArray = NSMutableArray()
var subArray = NSMutableArray()
let arrayDate = NSMutableArray()
for i in 0 ..< arrayData.count {
let msgDate = self.timeStampToDate(_timestamp: ((arrayData[i] as! NSDictionary).object(forKey: "date") as! String), _dateFormat: "dd/MM/yyyy")
print("dddt \(msgDate)")
// print("date array \(arrayDate) $$ msgDate \(msgDate)")
if arrayDate.contains(msgDate) {
subArray.add(arrayData[i])
}
else{
arrayDate.add(msgDate)
if arrayDate.count > 1 {
returnArray.add(subArray)
}
subArray = NSMutableArray()
subArray.add(arrayData[i])
}
}
if subArray != nil {
returnArray.add(subArray)
}
print(returnArray)
return returnArray
}
func timeStampToDate(_timestamp : String, _dateFormat : String) -> String{
// _dateFormat = "yyyy-MM-dd HH:mm:ss.SSSS"
var date = Date(timeIntervalSince1970: TimeInterval(_timestamp)!)
date += TimeInterval(Int(TimeZone.current.secondsFromGMT()) as NSNumber)
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "GMT") //Set timezone that you want
dateFormatter.locale = NSLocale.current
dateFormatter.dateFormat = _dateFormat
let strDate = dateFormatter.string(from: date)
return strDate
}
}
在这段代码中,我插入了硬编码的数组
(
{
date = 1516965600;
name = Bijender;
},
{
date = 1516965540;
name = ben;
},
{
date = 1516842180;
name = Deke;
},
{
date = 1516842000;
name = Veer;
},
{
date = 1515981900;
name = Ashfaq;
}
)
输出数组是
(
(
{
date = 1516965600;
name = Bijender;
},
{
date = 1516965540;
name = ben;
}
),
(
{
date = 1516842180;
name = Deke;
},
{
date = 1516842000;
name = Veer;
}
),
(
{
date = 1515981900;
name = Ashfaq;
}
)
)
我同意@Vasilii Muravev,您需要先清理您的 timestamp
对象,使用扩展或函数。顺便说一句,时间戳不是有效的 Swift 对象,除非它是您创建的自定义 class。
然后你可以为你的数据源创建一个字典。我将使用@Vasilii Muravev 的扩展名:
//var myKeys : [Date] = []
let sortedPeople = persons.sorted { [=10=].inscriptionDate.noTime() < .inscriptionDate.noTime() }
//break your array into a dictionary([Date : [Person]])
//personsSortedByDateInSections : [Date : [Person]] = [:]
for person in sortedPeople {
if personsSortedByDateInSections[person.inscriptionDate] != nil {
personsSortedByDateInSections[person.inscriptionDate]!.append(person)
} else {
personsSortedByDateInSections[person.inscriptionDate] = [person]
}
}
myKeys = setKeyArray(personSortedByDateInSections.keys)
这将为您提供一个字典对象,其中所有 Person
对象按 inscriptionDate
分组(分段)。然后您只需要填写您的 collectionView 委托和数据源方法。
override func numberOfSections(in: UICollectionView) -> Int {
return myKeys.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return personsSortedByDateInSections[myKeys[section]].count
}
更新:
正如您的评论中所述,使用 swift 字典获取键数组存在问题(我认为 swift 字典在早期版本中没有这个问题?我可能是错的)... .无论如何要解决这个问题我已经使用这个函数为 'keyArray' 设置了一个 class 变量。:
fileprivate func setKeysArray(_ keys: LazyMapCollection<Dictionary<Date, [Person]>, String) -> [Date]{
var keysArray = [Date]()
for key in keys {
keysArray.append(key)
}
return keysArray
}
我有 array
个 Person
。 Person object 之间有许多字段 inscriptionDate
(a timestamp
)。我必须从这个 array
创建一个 collectionView
但使用 sections
。每个部分都有一个 header 即 inscriptionDate
作为具有此格式 dd/mm/yyyy
的日期。我必须按 inscriptionDate
对 array
进行排序,但没有时间(仅格式 dd/mm/yyyy
),以便在 collectionView
中加载数据(考虑到这些部分)。我从另一个问题中发现了这个solution。但是在执行此操作之前如何对 array
进行排序?我该如何使用它:
order = NSCalendar.currentCalendar().compareDate(now, toDate: olderDate,
toUnitGranularity: .Day)
就我而言?
假设您的 inscriptionDate
是 Date
,您为什么不能对其进行排序?因为 Date
符合 Comparable
你所需要的只是
let sortedByDate = persons.sorted { [=10=].inscriptionDate < .inscriptionDate }
首先,您需要在排序前清理时间戳。您可以使用 Calendar
和 Date
扩展名来做到这一点:
extension Date {
func noTime() -> Date! {
let components = Calendar.current.dateComponents([.day, .month, .year], from: self)
return Calendar.current.date(from: components)
}
}
然后你只需要按日期排序你的数组而不用时间:
let sortedByDate = persons.sorted { [=11=].inscriptionDate.noTime() < .inscriptionDate.noTime() }
注意。 注意 Calendar
的 compareDate
函数,因为它只比较特定的组件。如果在此示例中: NSCalendar.currentCalendar().compareDate(now, toDate: olderDate, toUnitGranularity: .Day)
不同月份的日期相同,则比较结果将显示日期相等。
我为你写了一个代码我觉得这个代码对你有用。
//
// ViewController.swift
// sortData
//
// Created by Bijender singh on 26/01/18.
// Copyright © 2018 Bijender singh. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(_ animated: Bool) {
let myDataArray = NSMutableArray()
var myDataDic = NSMutableDictionary()
myDataDic.setValue("Bijender", forKey: "name")
myDataDic.setValue("1516965600", forKey: "date")
myDataArray.add(myDataDic)
myDataDic = NSMutableDictionary()
myDataDic.setValue("ben", forKey: "name")
myDataDic.setValue("1516965540", forKey: "date")
myDataArray.add(myDataDic)
myDataDic = NSMutableDictionary()
myDataDic.setValue("Deke", forKey: "name")
myDataDic.setValue("1516842180", forKey: "date")
myDataArray.add(myDataDic)
myDataDic = NSMutableDictionary()
myDataDic.setValue("Veer", forKey: "name")
myDataDic.setValue("1516842000", forKey: "date")
myDataArray.add(myDataDic)
myDataDic = NSMutableDictionary()
myDataDic.setValue("Ashfaq", forKey: "name")
myDataDic.setValue("1515981900", forKey: "date")
myDataArray.add(myDataDic)
print(myDataArray)
let sortedArray = self.sortDataWithDate(arrayData: myDataArray)
// sortedArray contane array which contan same date array
// you can use it according to you
// sortedArray.count is total diffrent dates in your array
// and (sortedArray.count[i] as! NSArray).count give you count of data of that date (0 < i < sortedArray.count)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func sortDataWithDate(arrayData : NSArray) -> NSArray {
// var chat: [ChatMessage]!
let returnArray = NSMutableArray()
var subArray = NSMutableArray()
let arrayDate = NSMutableArray()
for i in 0 ..< arrayData.count {
let msgDate = self.timeStampToDate(_timestamp: ((arrayData[i] as! NSDictionary).object(forKey: "date") as! String), _dateFormat: "dd/MM/yyyy")
print("dddt \(msgDate)")
// print("date array \(arrayDate) $$ msgDate \(msgDate)")
if arrayDate.contains(msgDate) {
subArray.add(arrayData[i])
}
else{
arrayDate.add(msgDate)
if arrayDate.count > 1 {
returnArray.add(subArray)
}
subArray = NSMutableArray()
subArray.add(arrayData[i])
}
}
if subArray != nil {
returnArray.add(subArray)
}
print(returnArray)
return returnArray
}
func timeStampToDate(_timestamp : String, _dateFormat : String) -> String{
// _dateFormat = "yyyy-MM-dd HH:mm:ss.SSSS"
var date = Date(timeIntervalSince1970: TimeInterval(_timestamp)!)
date += TimeInterval(Int(TimeZone.current.secondsFromGMT()) as NSNumber)
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "GMT") //Set timezone that you want
dateFormatter.locale = NSLocale.current
dateFormatter.dateFormat = _dateFormat
let strDate = dateFormatter.string(from: date)
return strDate
}
}
在这段代码中,我插入了硬编码的数组
(
{
date = 1516965600;
name = Bijender;
},
{
date = 1516965540;
name = ben;
},
{
date = 1516842180;
name = Deke;
},
{
date = 1516842000;
name = Veer;
},
{
date = 1515981900;
name = Ashfaq;
}
)
输出数组是
(
(
{
date = 1516965600;
name = Bijender;
},
{
date = 1516965540;
name = ben;
}
),
(
{
date = 1516842180;
name = Deke;
},
{
date = 1516842000;
name = Veer;
}
),
(
{
date = 1515981900;
name = Ashfaq;
}
)
)
我同意@Vasilii Muravev,您需要先清理您的 timestamp
对象,使用扩展或函数。顺便说一句,时间戳不是有效的 Swift 对象,除非它是您创建的自定义 class。
然后你可以为你的数据源创建一个字典。我将使用@Vasilii Muravev 的扩展名:
//var myKeys : [Date] = []
let sortedPeople = persons.sorted { [=10=].inscriptionDate.noTime() < .inscriptionDate.noTime() }
//break your array into a dictionary([Date : [Person]])
//personsSortedByDateInSections : [Date : [Person]] = [:]
for person in sortedPeople {
if personsSortedByDateInSections[person.inscriptionDate] != nil {
personsSortedByDateInSections[person.inscriptionDate]!.append(person)
} else {
personsSortedByDateInSections[person.inscriptionDate] = [person]
}
}
myKeys = setKeyArray(personSortedByDateInSections.keys)
这将为您提供一个字典对象,其中所有 Person
对象按 inscriptionDate
分组(分段)。然后您只需要填写您的 collectionView 委托和数据源方法。
override func numberOfSections(in: UICollectionView) -> Int {
return myKeys.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return personsSortedByDateInSections[myKeys[section]].count
}
更新: 正如您的评论中所述,使用 swift 字典获取键数组存在问题(我认为 swift 字典在早期版本中没有这个问题?我可能是错的)... .无论如何要解决这个问题我已经使用这个函数为 'keyArray' 设置了一个 class 变量。:
fileprivate func setKeysArray(_ keys: LazyMapCollection<Dictionary<Date, [Person]>, String) -> [Date]{
var keysArray = [Date]()
for key in keys {
keysArray.append(key)
}
return keysArray
}