我是创建应用程序的新手,我开始使用Swift进行iOS开发。我真的希望有人会花点时间帮助我,因为我现在很困难。所以我正在创建一个带有主 - 细节tableview的应用程序。我将使用Alamofire从外部获取我的数据,返回的数据将是JSON,我可以使用SwiftyJSON进行解析。
我能够很好地显示数据,这对我来说很好。但是我想要实现的目标,以及我似乎无法理解的是,如何使用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
}
最后,我有一个ViewController,它实现了必要的逻辑,以便使用返回的数据绘制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 :(得分:1)
根据您的需要,您需要实现tableview的2个委托方法:
func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int
func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]!
但您需要稍微修改一下您的模型,以使其更适合此类切片。
如果你的api将已经拆分的数据归还给我,请将歌曲分组保存在字典中:var songs:[String:[Song]?] = [:]
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
答案 1 :(得分:0)
在numberOfSectionsInTableView
中,您需要返回部分的数量。也许那是26,或者你可能不想显示空白部分。
在numberOfRowsInSection:
中,您需要返回该部分的行数。因此,如果部分0
为a
,请返回a
的行数。
在cellForRowAtIndexPath:
中,使用indexPath的row
和section
属性返回特定的单元格。
一个好的开始方法可能是将数据分解为数组,每个字母一个部分。
答案 2 :(得分:0)
解析响应时,您将获得一个字典,其中包含A,B,... Z作为键,相应的详细信息是值。您应该实现numberOfSectionsInTableView
以返回此词典中的键数,numberOfRowsInSection
以返回每个Alphabet键的entires数,并cellForRowAtIndexPath
显示正确的值。