2017-03-31 84 views
0

我目前使用3個獨立的數組來填充一個分段的UITableView,我想只使用一個數組進行過濾,但仍然維護我的表內部分。將3個單獨的字典數組轉換爲1個結構數組?

數據由單個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中不同的部分這單個陣列?如果是這樣,怎麼樣?

+1

你爲什麼不創建一個二維數組。外部數組保存每個部分的數組和內部數組保存每個部分中的項目?你可以在2D陣列上運行濾鏡 –

回答

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 ... 
} 
+0

完美!正是我需要感謝你。我需要解決一些問題,因爲我希望在一個空白區域中放置一行,以表示這裏沒有任何內容,我希望能夠關閉/關閉部分,即用戶可以選擇只顯示打開和關閉事件,開放和延期,或全部。 –

+1

要管理可見部分,請將數組(0 .. <3)替換爲部分標識符數組(例如,狀態字符串),只包含可見部分的值,直接在過濾器中使用EventStatus字段(那麼您將不再需要EventItem中的部分變量)。對於佔位符,您可以直接在eventList(帶有內部指示符)時將它們放在沒有其他位置的位置,並使匹配()函數始終匹配這些條目。 –

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

就像這樣,非常優雅。 但是,我得到一個錯誤值的元組類型'(viewController.EventItem,viewController.EventItem)'沒有值'EventStatus'。我正在打印eventsList,它絕對有... –

+0

對不起。 EventsList是我的數組:var eventsList = [EventItem]() 我也有一個用於搜索目的的過濾器:var filteredEventsList = [EventItem]() 首先檢查filteredEventsList的計數,如果> 0,則使用 –

+0

檢查'如果!array.isEmpty'。不要檢查'如果array.count> 0' –