UITableView切片

时间:2015-05-11 20:14:55

标签: ios iphone uitableview swift

我是创建应用程序的新手,我开始使用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.
    }


}

我知道这可能是教科书的内容,但我现在已经有三天了,我开始有点失去理智。所以我真的希望有人会花时间帮助我,并解决一些我可能做错的事情

提前致谢!

3 个答案:

答案 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]?] = [:]

然后在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

答案 1 :(得分:0)

numberOfSectionsInTableView中,您需要返回部分的数量。也许那是26,或者你可能不想显示空白部分。

numberOfRowsInSection:中,您需要返回该部分的行数。因此,如果部分0a,请返回a的行数。

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

一个好的开始方法可能是将数据分解为数组,每个字母一个部分

答案 2 :(得分:0)

解析响应时,您将获得一个字典,其中包含A,B,... Z作为键,相应的详细信息是值。您应该实现numberOfSectionsInTableView以返回此词典中的键数,numberOfRowsInSection以返回每个Alphabet键的entires数,并cellForRowAtIndexPath显示正确的值。