2015-05-11 44 views
0

我對創建應用程序非常陌生,我從Swift開始iOS開發。我真的希望有人會花一點時間來幫助我,因爲我現在很困難。所以我正在創建一個帶有主細節tableview的應用程序。我將使用Alamofire從外部獲取數據,並且返回的數據將是JSON,我可以使用SwiftyJSON進行分析。UITableView切片

我能夠顯示數據就好,這對我來說工作得很好。但是我想實現的目標以及我無法理解的東西是如何用titleForHeaderInSection按字母順序排列我的項目,並且能夠使用sectionIndexTitlesForTableView導航。

從我的API接收的數據看起來是這樣的(格式可改變,因爲我控制API):

{ 
    "A": [ 
     { 
      "id": "1", 
      "char": "A", 
      "title": "ABC", 
      "body": "Denne sang hedder ABC" 
     }, 
     { 
      "id": "2", 
      "char": "A", 
      "title": "Abel spandabel", 
      "body": "Denne sang hedder Abel spandabel" 
     }, 
     { 
      "id": "3", 
      "char": "A", 
      "title": "Aha aha aha", 
      "body": "Denne sang hedder Aha aha aha" 
     } 
    ], 
    "B": [ 
     { 
      "id": "4", 
      "char": "B", 
      "title": "Bussemand", 
      "body": "Denne sang hedder Bussemand" 
     }, 
     { 
      "id": "5", 
      "char": "B", 
      "title": "Balademager", 
      "body": "Denne sang hedder Balademager" 
     } 
    ], 
    "D": [ 
     { 
      "id": "6", 
      "char": "D", 
      "title": "Dukke mand", 
      "body": "Denne sang hedder Dukke mand" 
     }, 
     { 
      "id": "7", 
      "char": "D", 
      "title": "Dansevisen", 
      "body": "Denne sang hedder Dansevisen" 
     } 
    ] 
} 

然後,我有一個Song.swift文件定義了一些屬性,一個結構我個別項目。我看起來是這樣的:

struct Song { 
    var title : String 
    var body : String 
    var char : String 
} 

最後,我有一個實現以繪製的數據的tableview必要的邏輯視圖控制器返回

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 

    @IBOutlet weak var songsTableView: UITableView! 

    var songs = [Song]() 

    func addSong(song: Song) { 
     self.songs.append(song) 
    } 

    func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return songs.count 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell 

     var currentSong = songs[indexPath.row] 

     cell.textLabel?.text = currentSong.title 

     return cell 
    } 

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     var nextScreen = segue.destinationViewController as! SingleViewController 

     if let indexPath = self.songsTableView.indexPathForSelectedRow() { 
      let selectedSong = songs[indexPath.row] 
      nextScreen.currentSong = selectedSong 
     } 
    } 

    func getSongs() { 
     Alamofire.request(.GET, "http://MYAPI.COM") 
      .responseJSON { (_, _, data, _) in 
       let json = JSON(data!) 
       // TODO: Come up with some better names for the "subJson" 
       for (key: String, subJson: JSON) in json { 
        // TODO: Come up with some better names for the "subSubJson" 
        for (key: String, subSubJson: JSON) in subJson { 
         var title: String = subSubJson["title"].string! 
         var body: String = subSubJson["body"].string! 
         var char: String = subSubJson["char"].string! 

         var song = Song(title: title, body: body, char: char) 

         self.addSong(song) 
        } 
       } 
      self.songs.sort({$0.title < $1.title}) 

      self.songsTableView!.reloadData() 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     self.getSongs() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 

我知道這也許應該是教科書東西,但我現在已經呆了三天了,我開始有點失去主意了。所以我真的希望有人會花時間幫助我,並解決一些我可能做錯的事

在此先感謝!

+0

爲什麼不使用'NSJSONSerialization'的JSON解析?自iOS 5起可用。 –

回答

1

你想要的東西,你需要實現的tableview的2種委託方法:

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int 
func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! 

但你需要修改你的模型了一下,使之更適合這樣的切片的。

如果你的API返回的數據已經分裂成章節我會保持在字典分組的歌曲,像這樣:var songs:[String:[Song]?] = [:]

然後在API處理器我會做這樣的事情:

for (letter, songsJsonForLetter) in json.dictionaryValue { 
    for songJson in songsJsonForLetter.arrayValue { 
    var newSong = Song(title:songJson["title"].string!, body: songJson["bopy"].string!, char: letter) 
    if nil != self.songs[letter] { 
     self.songs[letter]!.append(newSong) 
    }else{ 
     self.songs[letter] = [newSong] 
    } 
    } 
} 

這樣你就可以將歌曲直接解析成字典,其中的關鍵字是字母["A",[Song1, Song2, Song3], "D":[Song4, Song5]]...

現在您只需要爲節索引所需的表視圖實現2個委託,事端摹狀:

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int { 
    return index 
    } 


    func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! { 
    return self.songs.keys.array.sorted{$0 < $1} 
    } 

,當然,修改代碼,獲取用於索引路徑歌曲在cellForRowAtIndePath喜歡的東西:

... 
let sectionLetter = sectionIndexTitlesForTableView(tableView)[indexPath.section] as! String 
     var currentSong = songs[sectionLetter]!.sorted{$0.title<$1.title}[indexPath.row] 
    ... 

PS。不要忘了也numberOfSections和rowsForSection恰克喜歡的東西:

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return songs.count 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
let sectionLetter = sectionIndexTitlesForTableView(tableView)[section] as! String 
    return songs[sectionLetter].count 
    } 

希望這會有所幫助,GL

+0

嗨,非常感謝您的回答。你能詳細說一下你的意思嗎?但是你需要修改你的模型來使它更適合這種切片。 – madsobel

+0

我的意思是,不要將歌曲保存爲數組,而應將其保存在字典中,其中鍵是第一個字母,值是包含該字母的歌曲的數組,例如。用var歌曲改變var songs = [Song]():[String:[Song]?] = [:],然後在我接下來寫的時候,只需填寫來自API的數據即可。這種方式更容易爲段索引標題提供服務,因爲它們是字典的關鍵字 –

0

numberOfSectionsInTableView中,您需要返回部分的數量。也許這是26,或者你可能不想顯示空白部分。

numberOfRowsInSection:中,您需要返回該部分的行數。因此,如果部分0a,請返回a的行數。

cellForRowAtIndexPath:中,使用indexPath的rowsection屬性返回特定的單元格。

開始的一個好方法可能是將數據分成數組,每個字母一個部分

0

當你解析響應時,你會得到一個字典,A,B,... Z作爲鍵,相應的細節是值。您應該執行numberOfSectionsInTableView以返回此字典中的密鑰數numberOfRowsInSection以返回每個Alphabet密鑰的條目數,並返回cellForRowAtIndexPath以顯示正確的值。