我目前正在使用3个独立的数组来填充分段的UITableView,我只想使用单个数组进行过滤,但仍然维护我的表中的部分。
数据由单个JSON字符串提供,然后我会迭代以创建单个“事件”的字典。然后根据'事件状态'的值,将其添加到三个数组之一(打开,关闭和延迟)。然后使用这些数组填充UITableView的每个部分。
let myDictionary: [String: String] = [
"EventID" : item["EventID"] as! String,
"EventTitle" : item["EventTitle"] as! String,
"EventSummary" : item["EventSummary"] as! String,
"EventStatus" : item["Status"] as! String
]
if (item["Status"] as! String == "Open") {
self.openEvents.append(myDictionary as AnyObject)
}
if (item["Status"] as! String == "Closed") {
self.closedEvents.append(myDictionary as AnyObject)
}
if (item["Status"] as! String == "") {
self.deferredEvents.append(myDictionary as AnyObject)
}
然后在cellForRowAt:
var tmpDict: [String: String] = ["":""]
if sectionHeaders[indexPath.section] == "Open" {
tmpDict = openEvents[indexPath.row] as! [String : String]
}
if sectionHeaders[indexPath.section] == "Closed" {
tmpDict = closedEvents[indexPath.row] as! [String : String]
}
if sectionHeaders[indexPath.section] == "Deferred" {
tmpDict = deferredEvents[indexPath.row] as! [String : String]
}
问题是,为了允许过滤这些数据,我必须针对三个不同的阵列运行过滤器,这意味着三个不同的过滤数据'阵列。这远非理想。
我想要实现的是拥有一个结构化数据阵列(与字典相对),用户可以过滤这些数据并将结果返回到单个过滤后的数据中。阵列。我在其他地方这样做效果很好,但是,这是一个单独的列表,而不是分段。
我有一个结构设置并按如下方式添加项目:
let data = EventItem(EventID: item["EventID"] as! String, EventTitle: item["EventTitle"] as! String, EventSummary: item["EventSummary"] as! String, EventStatus: item["Status"] as! String)
self.eventList.append(data)
并使用以下过滤:
filteredData = eventList.filter() {
($0.EventTitle.lowercased() as NSString).contains(searchText.lowercased()) || ($0.EventSummary.lowercased() as NSString).contains(searchText.lowercased())
}
eventsTable.reloadData()
是否可以将此单个数组拆分为TableView中的不同部分?如果是这样,怎么样?
答案 0 :(得分:0)
您可以使用filteredData
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
switch section {
case 0:
let sortedList = newItems.sorted { $0.eventStatus == "Open"}
return sortedList.count
case 1:
let sortedList = newItems.sorted { $0.eventStatus == "Closed"}
return sortedList.count
case 2:
let sortedList = newItems.sorted { $0.eventStatus == ""}
return sortedList.count
default:
return 0 // shouldn't happen
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var tmpDict: [String: String] = ["":""]
switch section {
case 0:
tmpDict = newItems.sorted { $0.eventStatus == "Open"}
case 1:
tmpDict = newItems.sorted { $0.eventStatus == "Closed"}
case 2:
tmpDict = newItems.sorted { $0.eventStatus == ""}
default:
return 0 // shouldn't happen
// setup cell
}
答案 1 :(得分:0)
我建议您对EventItem结构承担更多责任,以帮助处理数据源响应。然后,您可以使用二维数组来管理节和行内容。
例如:
struct EventItem
{
var EventID = ""
var EventTitle = ""
var EventSummary = ""
var EventStatus = ""
func matches(_ searchText:String) -> Bool
{
return EventTitle.lowercased().contains(searchText.lowercased())
|| EventSummary.lowercased().contains(searchText.lowercased())
}
var section:Int
{
return EventStatus == "Opened" ? 0
: EventStatus == "Closed" ? 1
: 2
}
}
// you can maintain an "master" array of events (or build them from the dictionary as needed)
// I' using an array to keep the example simple
var eventList:[EventItem] = []
// This 2D array in your controller will serve as the store for your table view data source
var sectionData:[[EventItem]] = []
// applying filter is one line once you've added utility functions to your struct
sectionData = Array(0..<3).map{ section in return eventList.filter{$0.section == section && $0.matches(searchText)} }
// responding to tableview data source protocol only requires one line
// (which will not change even if you break down your data into more sections)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{ return sectionData[section].count }
// getting to the data to populate the table view cell will be quite straightforward
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let rowData = sectionData[indexPath.section][indexPath.row]
// setup cell ...
}