ios - UITableView sectioning -
i quite new creating apps, , starting ios development swift. hope take bit of time me out, because rather stuck now. creating app master-detail tableview. fetch data externally using alamofire, , returned data json, can parse swiftyjson.
i able display data fine, working fine me. want achieve, , seem can't head around, how divide items in alphabetical sections titleforheaderinsection
, , able navigate around sectionindextitlesfortableview
.
the data received api looks (the format can changed, since control 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" } ] }
then have song.swift
file defines struct properties individual items. looks this:
struct song { var title : string var body : string var char : string }
finally, have viewcontroller implements necessary logic in order draw tableview data returned
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 better names "subjson" (key: string, subjson: json) in json { // todo: come better names "subsubjson" (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() // additional setup after loading view, typically nib. self.getsongs() } override func didreceivememorywarning() { super.didreceivememorywarning() // dispose of resources can recreated. } }
i know should text book stuff, i've been @ 3 days now, , starting lose mind bit. hope take time me out here, , address of things might wrong
thanks in advance!
for want need implement 2 delegate methods of tableview:
func tableview(tableview: uitableview, sectionforsectionindextitle title: string, atindex index: int) -> int func sectionindextitlesfortableview(tableview: uitableview) -> [anyobject]!
but you'd need modify model bit make more suitable kind of sectioning.
if api returns data splitted sections i'd keep songs grouped in dictionary so: var songs:[string:[song]?] = [:]
then in api handler i'd like:
for (letter, songsjsonforletter) in json.dictionaryvalue { 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] } } }
this way you'll have songs parsed directly dictionary key letter ["a",[song1, song2, song3], "d":[song4, song5]]...
now need implement 2 delegates table view needed section indexing, like:
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} }
and of course modify code gets song index path in cellforrowatindepath like:
... let sectionletter = sectionindextitlesfortableview(tableview)[indexpath.section] as! string var currentsong = songs[sectionletter]!.sorted{$0.title<$1.title}[indexpath.row] ...
ps. don't forget chage numberofsections , rowsforsection like:
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 }
hope helps, gl
Comments
Post a Comment