从Swift字典中分配UITableView单元格标签文本

时间:2018-09-10 20:16:15

标签: ios swift uitableview indexpath

我正在尝试从快速词典中获取一个值以显示为单元格文本。我遇到错误:

  

“任意”类型没有下标成员

cell.audioLabel.text = audiofiles["filetitle"] <-line producing error

我相信我可能未正确设置变量,正在使用didSelectRowAt从另一个表视图中使用segue传递值。

var audios = Array<Any>() <- gets from another controller

这是我当前的viewcontroller代码:

import UIKit

class DetailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var audioTable: UITableView!
    @IBOutlet weak var descText: UITextView!
    @IBOutlet weak var clickButton: UIButton!

    var practitle = String()
    var desc = String()
    var hasAudio = Int()
    var audios = Array<Any>()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.title = practitle

        descText.text = desc

        if hasAudio != 0 {
            clickButton.isHidden = false
        }

        print(audios)
    }

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

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "audiocell", for: indexPath) as! DetailViewCell

        let audiofiles = audios[indexPath.row]

        cell.audioLabel.text = audiofiles["filetitle"]

        return cell
    }

当我使用

print(audios)

我得到的结果是:

  

[demoApp.Audiofile(id:1,文件名:“示例文件一”,文件名:“ breath5mins”,文件格式:“ mp3”),demoApp.Audiofile(id:2,文件名:“示例文件二”,文件名:“ breath10mins”,文件格式:“ mp3”),demoApp.Audiofile(id:3,文件名:“示例文件3”,文件名:“ breath20mins”,文件格式:“ mp3”)]

如何使用文件名作为单元格的标签文本?

目标是显示标题并在单元格单击时打开另一个视图,并允许用户单击新视图上的按钮并播放mp3文件。

3 个答案:

答案 0 :(得分:2)

显然,该对象不是快速字典,它是自定义类或结构。

您正在与Swift的强类型系统作斗争。 不要这样做

静态类型声明#include <iostream> #include <vector> #include <functional> int func(const unsigned int &myInt) { std::cout << __func__ << "\nMy numb is " << myInt << std::endl; return myInt; } int main() { using function_t = std::function<int(const unsigned int&)>; std::vector<function_t> myVector; myVector.push_back(func); myVector[0](999); return 0; }

audios

,并使用点号表示法代替不安全的KVC(在这种情况下,该方式仍然无法正常工作)。

var audios = Array<AudioFile>()

答案 1 :(得分:1)

您已将数组声明为Array<Any>-这意味着该数组可以包含任何内容;数组中的元素甚至不必全部都相同。结果,Swift编译器不知道从audios[indexPath.row]得到什么类型的东西。它可以是字典,可以是数组,也可以是整数。当您尝试使用下标时,编译器会给您一个错误,因为它不知道项目是否支持下标-即Int不支持,而Any可以成为Int

如果知道实际类型,请不要在Swift中使用AnyAnyObject; Swift的类型安全性使其能够通过了解什么是类型来消除编译时的大量潜在运行时问题。

print语句看来,您的数组包含Audiofile实例(大概是您定义的结构或类,而不是字典)。因此,您应该正确声明audios

var audios = Array<Audiofile>()

然后您可以在cellForRow中访问对象的属性:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "audiocell", for: indexPath) as! DetailViewCell

    let audiofiles = audios[indexPath.row]

    cell.audioLabel.text = audiofiles.filetitle

    return cell
}

答案 2 :(得分:-1)

出现错误的原因是Any是一个没有定义的对象。您可以像这样将其转换为AudioFile

let audiofiles = audios[indexPath.row] as! AudioFile

如果audios仅是AudioFile的数组,则将其声明为这样,就可以按照您描述的方式使用它。