从 Swift 字典中分配 UITableView Cell 标签文本
Posted
技术标签:
【中文标题】从 Swift 字典中分配 UITableView Cell 标签文本【英文标题】:Assign UITableView Cell label text from Swift dictionary 【发布时间】:2018-09-10 20:16:14 【问题描述】:我正在尝试从 swift 字典中获取一个值以显示为单元格文本。我收到错误:
类型 'Any' 没有下标成员
cell.audioLabel.text = audiofiles["filetitle"] <-line producing error
我相信我可能错误地设置了变量,该值是通过使用 didSelectRowAt 从另一个 tableview 中的 segue 传递的。
var audios = Array<Any>() <- gets from another controller
这是我当前的视图控制器代码:
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, filetitle: "示例文件一", filename: "breath5mins", fileformat: "mp3"), demoApp.Audiofile(id: 2, filetitle: "示例文件二", filename : "breath10mins", fileformat: "mp3"), demoApp.Audiofile(id: 3, filetitle: "示例文件三", filename: "breath20mins", fileformat: "mp3")]
如何使用文件标题作为单元格的标签文本?
目标是显示标题并在单击单元格时打开另一个视图,并允许用户单击新视图上的按钮并播放 mp3 文件。
【问题讨论】:
demoApp.Audiofile(...)
的类型是什么?
不要将数组声明为Array<Any>
。用它包含的实际类型正确声明它Array<AudioFile>
。
我更改了它,但我得到该行的 Use of undeclared type 'AudioFile' 错误
@RonModz type(of: demoApp.Audiofile(id: 1, filetitle: "Sample file one", filename: "breath5mins", fileformat: "mp3"))
打印什么?
我的评论有错字;我输入了 AudioFile
而不是 Audiofile
- 我的手指自动将类型名称驼峰化为大写 F
【参考方案1】:
显然该对象不是 Swift 字典,它是一个自定义类或结构。
您正在与 Swift 强大的类型系统作斗争。 不要这样做。
用static类型声明audios
var audios = Array<AudioFile>()
并使用点符号代替不安全的 KVC(在这种情况下无论如何都不起作用)。
cell.audioLabel.text = audiofiles.filetitle
【讨论】:
我进行了更改,但我得到了 - 线程 1:致命错误:在展开可选值时意外发现 nil 崩溃与此代码无关。我们正在处理非可选项。 @RonModz 看看at this - 你可能还没有在故事板和班级之间连接插座。【参考方案2】:您已将您的数组声明为Array<Any>
- 这意味着该数组可以包含任何东西;数组的元素甚至不需要都是相同的类型。结果,Swift 编译器不知道它从audios[indexPath.row]
得到什么类型的东西;它可以是字典,可以是数组,也可以是整数。当您尝试使用下标时,编译器会给您一个错误,因为它不知道项目是否支持下标 - 即 Int
不支持,Any
可能是 @987654325 @。
如果您知道实际类型,请不要在 Swift 中使用 Any
或 AnyObject
; 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
【讨论】:
type(of: demoApp.Audiofile(id: 1, filetitle: "Sample file one", filename: "breath5mins", fileformat: "mp3"))
是Array<Any>
,也许建议声明一个struct Audiofile
OP 有一个包含三个元素的数组。这些元素是Audiofile
s(不管是什么,大概是一个结构或类)
查看问题下的最后一个cmets
是的,因为他们正在他们的接收对象中打印属性的详细信息,他们已将其声明为 Array<Any>
,所以这就是 Swift 在打印 audios
时显示的内容。他们向这个班级发送的是Array<Audiofile>
。正如我所解释的,他们需要修复接收器属性上的类型。他们已经有了这个结构,他们只是通过使用Any
“丢失”它
demoApp.Audiofile(...)
本身就是 Array<Any>
【参考方案3】:
您收到错误的原因是Any
是一个没有定义的对象。您可以将其转换为 AudioFile
,如下所示:
let audiofiles = audios[indexPath.row] as! AudioFile
如果 audios
是 AudioFile
的数组,则仅声明它,您可以按照您描述的方式使用它。
【讨论】:
你需要有条件的或强制的向下转型;您不能使用从Any
到Audiofile
的简单向下转换;但是,最好完全取消使用Any
。以上是关于从 Swift 字典中分配 UITableView Cell 标签文本的主要内容,如果未能解决你的问题,请参考以下文章
UITableView 自定义 Cell iPhone 使用 Swift 语言