ios 将按日期分隔的部分添加到 Swift 中的 UITableView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26596090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding sections, separated by dates, to UITableView in Swift
提问by maxpetter
I'm a complete rookie at Swift and iOS programming so you'll have to forgive the perhaps simple question.
我是 Swift 和 iOS 编程的完全新手,所以你必须原谅这个可能很简单的问题。
I've created a tableView which displays the contents of an array (strings) at the press of a button. Now, I'd like to "group" these strings in tableView sections, sorted by date.
我创建了一个 tableView,它在按下按钮时显示数组(字符串)的内容。现在,我想在 tableView 部分中“分组”这些字符串,按日期排序。
In more detail: When the user taps the button, the string should be inserted at index 0 of the array and be displayed in a section with a header of todays date. If there's values older than today's date in the array, these should be displayed in a separate section for that date. Each section should correspond to a 24 hour day and display all the strings added during that day.
更详细地说:当用户点击按钮时,字符串应插入数组的索引 0 处,并显示在带有今天日期标题的部分中。如果数组中存在早于今天日期的值,则这些值应显示在该日期的单独部分中。每个部分应对应一天 24 小时,并显示当天添加的所有字符串。
Here's some sample code of what I've achieved so far:
这是我到目前为止所取得的一些示例代码:
var testArray[String]()
var sectionsInTable[String]()
@IBOutlet weak var testTable: UITableView!
@IBAction func saveButton(sender: AnyObject) {
testArray.insert("\(strTest)", atIndex: 0)
testTable.reloaddata()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sectionsInTable.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return testArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel.text = String(testArray[indexPath.row])
return cell
}
I really don't know how to manage the sections part. Hopefully someone can point me in the right direction. Thanks!
我真的不知道如何管理部分。希望有人能指出我正确的方向。谢谢!
回答by Adam Bardon
I was in need for something similar, and while Ron Fessler's solution works, when there's a lot of sections/rows, it took a very long time for table to load data, and even after that it wasn't much responsive. Main issue there I think is getSectionItems function as it will always go through all of items...
我需要类似的东西,虽然Ron Fessler的解决方案有效,但当有很多部分/行时,表加载数据需要很长时间,即使在此之后它也没有太多响应。我认为那里的主要问题是 getSectionItems 函数,因为它总是会遍历所有项目......
My solution:
我的解决方案:
struct TableItem {
let title: String
let creationDate: NSDate
}
var sections = Dictionary<String, Array<TableItem>>()
var sortedSections = [String]()
@IBAction func saveButton(sender: AnyObject) {
let date:String = "your date in string..."
//if we don't have section for particular date, create new one, otherwise we'll just add item to existing section
if self.sections.indexForKey(date) == nil {
self.sections[date] = [TableItem(title: name, creationDate: date)]
}
else {
self.sections[date]!.append(TableItem(title: name, creationDate: date))
}
//we are storing our sections in dictionary, so we need to sort it
self.sortedSections = self.sections.keys.array.sorted(>)
self.tableView.reloadData()
}
tableView dataSource methods:
tableView 数据源方法:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[sortedSections[section]]!.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell")
let tableSection = sections[sortedSections[indexPath.section]]
let tableItem = tableSection![indexPath.row]
cell.titleLabel?.text = tableItem.title
return cell
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sortedSections[section]
}
回答by Ron Fessler
I would usually do this with Core Data and NSFetchedResultsControllersince it has built-in methods for getting sections.
我通常会用 Core Data 和NSFetchedResultsController来做这件事,因为它有用于获取部分的内置方法。
However, I'll answer the question without using Core Data. The code is a little messier but here we go...
但是,我将在不使用 Core Data 的情况下回答这个问题。代码有点混乱,但我们开始......
First, you have to create an object that will store both the date and the text. The testArray will be an array of these objects, instead of a String array. For example:
首先,您必须创建一个对象来存储日期和文本。testArray 将是这些对象的数组,而不是 String 数组。例如:
class DateTextItem: NSObject {
var text: String = ""
var insertDate: NSDate = NSDate()
}
var testArray = [DateTextItem]()
Then when the saveButton is hit, we'll create and add the DateTextItem object. We'll also add the date to the sectionsInTable if it doesn't already exist.
然后当 saveButton 被点击时,我们将创建并添加 DateTextItem 对象。如果它不存在,我们还会将日期添加到sectionsInTable。
@IBAction func saveButton(sender: AnyObject) {
let newItem = DateTextItem()
newItem.text = "Test \(testArray.count)"
// this is for development only
// increment the date after 2 records so we can test grouping by date
if testArray.count >= (testArray.count/2) {
let incrementDate = NSTimeInterval(86400*(testArray.count/2))
newItem.insertDate = NSDate(timeIntervalSinceNow:incrementDate)
}
testArray.append(newItem)
// this next bit will create a date string and check if it's in the sectionInTable
let df = NSDateFormatter()
df.dateFormat = "MM/dd/yyyy"
let dateString = df.stringFromDate(newItem.insertDate)
// create sections NSSet so we can use 'containsObject'
let sections: NSSet = NSSet(array: sectionsInTable)
// if sectionsInTable doesn't contain the dateString, then add it
if !sections.containsObject(dateString) {
sectionsInTable.append(dateString)
}
self.tableView.reloadData()
}
Next, I created a function to get the items in a section since we need it in a couple places.
接下来,我创建了一个函数来获取部分中的项目,因为我们在几个地方需要它。
func getSectionItems(section: Int) -> [DateTextItem] {
var sectionItems = [DateTextItem]()
// loop through the testArray to get the items for this sections's date
for item in testArray {
let dateTextItem = item as DateTextItem
let df = NSDateFormatter()
df.dateFormat = "MM/dd/yyyy"
let dateString = df.stringFromDate(dateTextItem.insertDate)
// if the item's date equals the section's date then add it
if dateString == sectionsInTable[section] as NSString {
sectionItems.append(dateTextItem)
}
}
return sectionItems
}
Finally, here is what the Table View Data Source methods look like
最后,这是表视图数据源方法的样子
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sectionsInTable.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.getSectionItems(section).count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
// get the items in this section
let sectionItems = self.getSectionItems(indexPath.section)
// get the item for the row in this section
let dateTextItem = sectionItems[indexPath.row]
cell.textLabel.text = dateTextItem.text
return cell
}
// print the date as the section header title
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionsInTable[section]
}
回答by Vincent
You have to make an array for each day (called dayArray[] for example) and add it to sectionInTable[] and do something like that :
您必须为每一天创建一个数组(例如,称为 dayArray[])并将其添加到 sectionInTable[] 并执行以下操作:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sectionsInTable.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return sectionsInTable.objectAtIndex(section).count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel.text = String(sectionInTable.objectAtIndex(indexPath.section).objectAtIndex(indexPath.row))
return cell
}
Sorry if I did mistakes, I'm not familiar with swift but I think the idea can help.
抱歉,如果我犯了错误,我对 swift 不熟悉,但我认为这个想法会有所帮助。
回答by Ernest Jordan Chechelski
I implemented generic algorithm to sort out any objects which can by identified by some day. I guess would be helpful in such cases:
我实现了通用算法来整理任何可以在某一天识别的对象。我想在这种情况下会有所帮助:
protocol DayCategorizable {
var identifierDate: Date { get }
}
extension Array where Element: DayCategorizable {
var daySorted: [Date: [Element]] {
var result: [Date: [Element]] = [:]
let calendar = Calendar.current
self.forEach { item in
let i = calendar.startOfDay(for: item.identifierDate)
if result.keys.contains(i) {
result[i]?.append(item)
} else {
result[i] = [item]
}
}
return result
}
}