快速更改不同类中的一个类的属性(特别是 UILabel)
Posted
技术标签:
【中文标题】快速更改不同类中的一个类的属性(特别是 UILabel)【英文标题】:change a property from one class in a different class swift (specifically a UILabel) 【发布时间】:2015-08-09 03:36:35 【问题描述】:我正在尝试从另一个类内部更改 UITableView(一个类的属性)中的 UILabel 的文本,但我遇到了麻烦。代码是这样的(问题在最后,在myDataSource的didSelectRowAtIndexPath方法中)
视图控制器
class ViewController: UIViewController
//MARK: Properties
@IBOutlet weak var myTableView: UITableView!
@IBOutlet weak var myLabel: UILabel!
//needed so data from myDataSource is retained by ViewController and not just thrown away
let importedDataSource = myDataSource()
override func viewDidLoad()
super.viewDidLoad()
myTableView.dataSource = myDataSource()
myTableView.delegate = myDataSource()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
UITableViewDataSource 和委托
class myDataSource: NSObject, UITableViewDataSource, UITableViewDelegate
let cellIdentifier = "myTableViewCell"
let myArray = ["Label one", "Label two", "Label three"]
//MARK: TableViewDataSource
func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return myArray.count
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! myTableViewCell
cell.myCellLabel.text = myArray[indexPath.row]
return cell
//MARK:TableView Delegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
//This Line Here returns the error
ViewController().myLabel.text = "test"
//I want the end product to be ViewController().myLabel.text = myArray[indexPath.row], but left it as "test" just to simplify and isolate the error
(还有一个名为 myTableViewCell 的 UITableViewCell 类,但我省略了它以使其更短)
在选择其中一行时,运行会返回“致命错误:在展开可选值时意外发现 nil”。我应该如何调用 myLabel 以避免这个问题?我已经尝试通过 ctrl 将它从情节提要中拖动,将它作为 myDataSource 中的 @IBOutlet 连接起来,但正如我所料,它只允许我将它连接到视图控制器。
抱歉,代码与两个名称相似的标签有点混淆。我正在尝试调用在 ViewController 中创建的 myLabel var(第一段代码),而不是在 myTableViewCell 中创建的 myCellLabel(未显示)
【问题讨论】:
【参考方案1】:您看到消息“致命错误:在展开可选值时意外发现 nil”的原因是因为您试图将值分配给nil
.
在你的 UITableViewDelegate 方法 tableView(_:didSelectRowAtIndexPath:)
的实现中声明:
ViewController().myLabel.text = "test"
-
创建
ViewController
类的新实例(ViewController()
所做的)
访问新实例的myLabel
属性(回想一下,在类的声明中,您将此属性定义为UILabel!
类型,隐式解包的可选UILabel
,隐式解包的选项开始生命作为nil
,直到它们被赋值)
尝试将“test”分配给 myLabel
的 text
属性 - 但正如我们刚才提到的,myLabel
是 nil
,这就是您收到错误消息的原因
编辑
为了帮助您实现“尝试更改 UILabel 的文本”(该标签是您的 ViewController
实例的属性 myLabel
)的既定目标,路由我推荐的是:
ViewController
类采用UITableViewDelegate
协议
在ViewController
类中实现UITableViewDelegate
协议方法,它们将可以直接访问myLabel
属性
完成此操作后,该委托方法的实现(现在位于 ViewController
类中)将如下所示:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
myLabel.text = myTableView.dataSource.myArray[indexPath.row]
...虽然这会起作用,但即使这样也可以改进 - 我建议您查看 Apple 的 Table View Programming Guide
此外,除非有令人信服的理由不这样做,否则我还建议您让您的 ViewController
类充当您的 UITableViewDataSource
- 来自 Table View Programming Guide:“[t]he创建表视图的类通常通过采用 UITableViewDataSource 和 UITableViewDelegate 协议使自己成为数据源和委托”(参见section)
【讨论】:
谢谢!这有帮助。但是,如果我试图清理一个拥挤的 ViewController 类并希望委托和数据源与视图控制器分开,那么从数据源/委托类内部设置标签(在视图控制器中创建)的最简单方法是什么? 【参考方案2】:您需要获取被点击的实际表格视图单元格才能访问它的变量。使用cellForRowAtIndexPath
。它看起来像这样:
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
if let myCell = tableView.cellForRowAtIndexPath(indexPath) as? myTableViewCell
myCell.myLabel.text = "test"
【讨论】:
抱歉,代码与两个名称相似的标签有点混淆。我正在尝试调用在 ViewController 中创建的 myLabel var(第一段代码),而不是在 myTableViewCell 中创建的 myCellLabel(未显示)。标签在 TableView 之外,但我希望它更改为 myCellLabel 中的文本,就像您选择某些内容的下拉菜单一样,您的选择将成为标签的文本以上是关于快速更改不同类中的一个类的属性(特别是 UILabel)的主要内容,如果未能解决你的问题,请参考以下文章