3.构建数据层
按照官方sample,我们使用简单的plist来保存数据(当然使用内置也ok)。该plist既是我们列表中需要显示的内容。
1.将化学元素的数据整理为Elements.plist,该plist的结构为Array<Dictionary>(表示为ArrayList<Map<String,Object>>)。
dictionary中包含若干键值对,但一定要保证每个dictionary键值对的键和值的类型一致,这样我们才能够进行数据的解析。如图。
2. 在ElementDataModel目录下创建PKOElementDataModel类,作为化学元素的实体类,其中声明plist中所包含的键值对(由于部分属性没有使用,我这里就偷个懒省略了)。
由于我们的需求是要根据化学元素的状态种类来显示不同的底色,所以我们这里声明两个图片类型的属性,一个作为列表中行的左侧图标,另一个作为明细页面的展示用背景图,并重写他们的get方法,根据化学元素的状态种类来返回所需要的图片。
由于我们从plist仅能获得dictionary,所以我们需要进行转换,将从plist读出的dictionary转换为PKOElementDataModel对象,于是我们要写一个转换方法initWithDictionary(aDictionary : NSDictionary) ->PKOElementDataModel。
代码如下。
- import UIKit
-
- class PKOElementDataModel {
-
- var atomicNumber:Int = 0
- var name:String = ""
- var symbol:String = ""
- var state:String = ""
- var atomicWeight:String = ""
- var discoveryYear:String = ""
- var group:Int = 0
- var period:Int = 0
-
- var imageForDetailElementTileView:UIImage{
- get{
- return UIImage(named:self.state+"_256")
- }
- }
-
- var imageForCellIconElementView:UIImage{
- get{
- return UIImage(named:self.state+"_37")
- }
- }
-
- func initWithDictionary(aDictionary : NSDictionary) ->PKOElementDataModel{
- self.atomicNumber = aDictionary["atomicNumber"] as Int
- self.atomicWeight = aDictionary["atomicWeight"] as String
- self.discoveryYear = aDictionary["discoveryYear"] as String
- self.name = aDictionary["name"] as String
- self.symbol = aDictionary["symbol"] as String
- self.state = aDictionary["state"] as String
- self.group = aDictionary["group"] as Int
- self.period = aDictionary["period"] as Int
- return self
- }
- }
3.构建好了实体类后,我们需要一个能够从plist读取数据的服务类PKOElementDataService,该类声明了我们展示列表需要的多种array及dictionary实体,并在类初始化时解析plist并组装对应的array及dictionary。
首先,我们需要一个单例的服务,所以需要创建一个单例对象sharedElementDataService,这里用了gcd技术,保证单例。 其次,由于需求要不同维度的数据,所以我们需要按照不同维度进行分类和排序。 代码如下。
- import UIKit
-
- class PKOElementDataService {
- var elementDictionarys = [String:PKOElementDataModel]()
-
- var symbolLetterArray = [String]()
- var stateArray = [String]()
-
- var elementByNameArray = [PKOElementDataModel]()
- var elementByNumberArray = [PKOElementDataModel]()
- var elementSymbolDictionarys = [String:[PKOElementDataModel]]()
- var elementStateDictionarys = [String:[PKOElementDataModel]]()
-
- struct Inner {
- static var instance: PKOElementDataService?
- static var token: dispatch_once_t = 0
- }
-
- class var sharedElementDataService: PKOElementDataService {
- dispatch_once(&Inner.token) {
- Inner.instance = PKOElementDataService()
- }
- return Inner.instance!
- }
-
- init() {
- self.initElementArray()
- }
-
- func initElementArray() {
- var thePath = NSBundle.mainBundle().pathForResource("Elements", ofType: "plist")!
-
- var elementArray = NSArray(contentsOfFile: thePath)
-
- self.elementDictionarys = [String:PKOElementDataModel]()
- self.elementStateDictionarys = [String:[PKOElementDataModel]]()
- self.elementSymbolDictionarys = [String:[PKOElementDataModel]]()
-
- self.stateArray = [String]()
- self.symbolLetterArray = [String]()
-
- for elementArrayDictionary in elementArray {
-
- var elementDataModel = PKOElementDataModel().initWithDictionary(elementArrayDictionary as NSDictionary)
- self.elementDictionarys[elementDataModel.name] = elementDataModel
- if (self.elementStateDictionarys[elementDataModel.state] != nil) {
- self.elementStateDictionarys[elementDataModel.state]?.append(elementDataModel)
- } else {
- self.stateArray.append(elementDataModel.state)
- self.elementStateDictionarys[elementDataModel.state] = [PKOElementDataModel]()
- self.elementStateDictionarys[elementDataModel.state]?.append(elementDataModel)
- }
-
- var symbolLetter = elementDataModel.symbol.substringToIndex(advance(elementDataModel.symbol.startIndex, 1))
-
- if (self.elementSymbolDictionarys[symbolLetter] != nil) {
- self.elementSymbolDictionarys[symbolLetter]?.append(elementDataModel)
- } else {
- self.symbolLetterArray.append(symbolLetter)
-
- self.elementSymbolDictionarys[symbolLetter] = [PKOElementDataModel]()
- self.elementSymbolDictionarys[symbolLetter]?.append(elementDataModel)
- }
- }
-
- self.elementByNameArray = self.presortElementsByName()
-
- self.elementByNumberArray = self.presortElementsByNumber()
-
- self.symbolLetterArray = self.presortSymbolLetters()
- for letter in self.symbolLetterArray {
- self.presortElementsBySymbol(letter as String)
- }
-
- self.stateArray = self.presortStates()
- for state in self.stateArray {
- self.presortElementsByState(state as NSString)
- }
- }
-
-
- func presortElementsByName() -> [PKOElementDataModel] {
- var values = self.elementDictionarys.values
- var sortedElements = values.array.sorted({
- (s1, s2) -> Bool in
- return s2.name > s1.name
- })
- return sortedElements
- }
-
-
- func presortElementsByNumber() -> [PKOElementDataModel] {
- var values = self.elementDictionarys.values
- var sortedElements = values.array.sorted({
- (s1 , s2) -> Bool in
- return s1.atomicNumber > s2.atomicNumber
- })
- return sortedElements
- }
-
-
- func presortSymbolLetters() -> [String] {
- var keys = self.elementSymbolDictionarys.keys
- var sortedElement = keys.array.sorted({
- (s1 , s2) ->Bool in
- return s2 > s1
- })
- return sortedElement
- }
-
-
- func presortElementsBySymbol(letter : String) {
- self.elementSymbolDictionarys[letter]?.sort({
- (s1 , s2) ->Bool in
- return s1.name > s2.name
- })
- }
-
-
- func presortStates () -> [String]{
- var keys = self.elementStateDictionarys.keys
- var sortedElements = keys.array.sorted({
- (s1 , s2) ->Bool in
- return s2 > s1
- })
- return sortedElements
- }
-
-
- func presortElementsByState (state : String) {
-
- self.elementStateDictionarys[state]?.sort({
- (s1 , s2) ->Bool in
- return s2.name > s1.name
- })
- }
- }
4.由于我们需要将组装好的数据应用于tableView,而tableView提供一种方便的做法,就是实现UITableViewDatasource类,并重写其中方法。
我们先来构建一个定义这4类数据集的协议PKOTableDataSourceProtocol: UITableViewDataSource,当然,其中应包含一个方法,即通过索引获取数据对象。
代码如下。
- import UIKit
-
- protocol PKOTableDataSourceProtocol: UITableViewDataSource{
-
- var name: String{ get }
- var navigationBarName: String{ get }
- var tabBarImage: UIImage{ get }
- var tableViewStyle: UITableViewStyle{ get }
-
- func elementDataModelForIndexPath(indexPath: NSIndexPath) ->PKOElementDataModel
- }
5.构造4个类,实现PKOTableDataSourceProtocol协议,实现UITableViewDataSource需要实现的tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell、tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int两个方法;以及PKOTableDataSourceProtocol需要实现的elementDataModelForIndexPath(indexPath: NSIndexPath) ->PKOElementDataModel方法;当然根据不同需求可以实现UITableViewDataSource中其他的方法。
代码如下。我只粘了2段具有代表性的,其他请下载源码
- import UIKit
-
- class PKOTableByNameDataSource: NSObject, PKOTableDataSourceProtocol {
-
- var name : String{
- get{
- return "Test1"
- }
- }
-
- var navigationBarName : String{
- get{
- return "test1"
- }
- }
-
- var tabBarImage : UIImage{
- get{
- return UIImage(named: "name_tab")
- }
- }
-
- var tableViewStyle : UITableViewStyle{
- get{
- return UITableViewStyle.Plain
- }
- }
-
- func elementDataModelForIndexPath(indexPath: NSIndexPath) -> PKOElementDataModel {
- return PKOElementDataService.sharedElementDataService.elementByNameArray[indexPath.row]
- }
-
-
- func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
- var cell = tableView.dequeueReusableCellWithIdentifier("ElementTableViewCell", forIndexPath: indexPath) as PKOElementTableViewCell
- var element = self.elementDataModelForIndexPath(indexPath)
- cell.element = element
- return cell
- }
-
-
- func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return PKOElementDataService.sharedElementDataService.elementByNameArray.count
- }
-
- }
- import UIKit
-
- class PKOTableByStateDataSource: NSObject, PKOTableDataSourceProtocol {
-
- var name : String{
- get{
- return "Test4"
- }
- }
-
- var navigationBarName : String{
- get{
- return "test4"
- }
- }
-
- var tabBarImage : UIImage{
- get{
- return UIImage(named: "state_tab")
- }
- }
-
- var tableViewStyle : UITableViewStyle{
- get{
- return UITableViewStyle.Plain
- }
- }
-
- func elementDataModelForIndexPath(indexPath: NSIndexPath) -> PKOElementDataModel {
- var state = PKOElementDataService.sharedElementDataService.stateArray[indexPath.section]
- return PKOElementDataService.sharedElementDataService.elementStateDictionarys[state]![indexPath.row]
- }
-
-
- func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {
- return PKOElementDataService.sharedElementDataService.stateArray[section]
- }
-
-
- func sectionIndexTitlesForTableView(tableView: UITableView) -> [String] {
- return PKOElementDataService.sharedElementDataService.stateArray
- }
-
- func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
- var cell = tableView.dequeueReusableCellWithIdentifier("ElementTableViewCell", forIndexPath: indexPath) as PKOElementTableViewCell
- var element = self.elementDataModelForIndexPath(indexPath)
- cell.element = element
- return cell
- }
-
- func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- var state = PKOElementDataService.sharedElementDataService.stateArray[section]
- return PKOElementDataService.sharedElementDataService.elementStateDictionarys[state]!.count
- }
-
-
- func numberOfSectionsInTableView(tableView: UITableView) -> Int {
- return PKOElementDataService.sharedElementDataService.stateArray.count
- }
-
- }
原文地址:http://blog.csdn.net/ooppookid/article/details/40373277