简体   繁体   English

从另一个班级的一个班级快速更改属性(特别是UILabel)

[英]change a property from one class in a different class swift (specifically a UILabel)

I'm trying to change the text of a UILabel in a UITableView (a property of one class,) from inside another class, but I'm having trouble. 我正在尝试从另一个类的内部更改UITableView(一个类的属性)中的UILabel的文本,但是遇到了麻烦。 The code looks like this (The problem is at the end, in the didSelectRowAtIndexPath method of myDataSource) 代码看起来像这样(问题出在最后,在myDataSource的didSelectRowAtIndexPath方法中)

The View Controller 视图控制器

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()}

}

The UITableViewDataSource and Delegate 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
     }

}

(there's also a UITableViewCell class called myTableViewCell, but I left it out to be shorter) (还有一个名为myTableViewCell的UITableViewCell类,但我将其省略了)

Running returns "fatal error: unexpectedly found nil while unwrapping an Optional value" upon selecting one of the rows. 选择其中一行时,运行将返回“致命错误:在展开可选值时意外发现nil”。 How should I call myLabel so as to avoid this problem? 我应该如何调用myLabel以避免出现此问题? I've tried hooking it up as an @IBOutlet inside myDataSource by ctrl-dragging it from the storyboard, but as I expected, it only lets me connect it to the view controller. 我尝试通过ctrl从情节提要中将其作为myDataSource中的@IBOutlet挂钩,但是正如我所期望的,它只允许我将其连接到视图控制器。

sorry, the code is a bit confusing with the two similarly named labels. 抱歉,代码与两个名称相似的标签有些混淆。 I'm trying to call the myLabel var created in the ViewController (first piece of code), not the myCellLabel created in myTableViewCell (not shown) 我正在尝试调用在ViewController中创建的myLabel变量(第一段代码),而不是在myTableViewCell中创建的myCellLabel(未显示)

You need to get the actual table view cell that was tapped in order to access it's variables. 您需要获取被点击才能访问其变量的实际表视图单元格。 Use cellForRowAtIndexPath . 使用cellForRowAtIndexPath It'll look something like this: 它看起来像这样:

func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    if let myCell = tableView.cellForRowAtIndexPath(indexPath) as? myTableViewCell {
        myCell.myLabel.text = "test"
    }
}

The reason you are seeing the message " fatal error: unexpectedly found nil while unwrapping an Optional value " is because you are trying to assign a value to a property of nil . 您看到消息“ 致命错误:解开可选值时意外发现nil ”的原因是,您正在尝试将值分配给nil的属性。

In the implementation of your UITableViewDelegate method tableView(_:didSelectRowAtIndexPath:) the statement: 在实现UITableViewDelegate方法tableView(_:didSelectRowAtIndexPath:)的语句中:

ViewController().myLabel.text = "test"

  1. creates a new instance of your ViewController class (that is what ViewController() does) 创建您的ViewController类的新实例(这就是ViewController()作用)
  2. accesses the myLabel property of the new instance (recall that in your declaration of the class you defined this property to be of type UILabel! , an implicitly-unwrapped optional UILabel , and implicitly-unwrapped optionals begin life as nil until they are assigned a value) 访问新实例的myLabel属性(回想一下,在类的声明中,您将该属性定义为UILabel!类型,一个隐式展开的可选UILabel ,以及隐式展开的可选选项以nil开头,直到它们被赋值为止)
  3. tries to assign "test" to the text property of myLabel - but as we just noted, myLabel is nil and this is why you are receiving the error message 尝试将“ test”分配给myLabeltext属性-但是正如我们刚刚指出的, myLabelnil ,这就是为什么您收到错误消息的原因

EDIT 编辑

In an effort to assist you in your stated goal of " trying to change the text of a UILabel " (that label being the property myLabel of your ViewController instance), the route I would recommend is: 为了帮助您实现“ 尝试更改UILabel的文本 ”(该标签为ViewController实例的myLabel属性)的既定目标,我建议的路线是:

  • have your ViewController class adopt the UITableViewDelegate protocol 让您的ViewController类采用UITableViewDelegate协议
  • implement your UITableViewDelegate protocol methods inside of your ViewController class, where they will have direct access to the myLabel property ViewController类中实现UITableViewDelegate协议方法,在这些方法中,它们可以直接访问myLabel属性

once you've done this, your implementation of that delegate method (now residing inside of your ViewController class) would look like: 完成此操作后,该委托方法的实现(现在位于ViewController类内部)将如下所示:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {  
  myLabel.text = myTableView.dataSource.myArray[indexPath.row]
}

...and while this will work, even this can be improved - I recommend you check out Apple's Table View Programming Guide ...虽然这行得通,但甚至可以改善-我建议您查阅Apple的《 Table View编程指南》

furthermore, unless there is a compelling reason not to, I also recommend that you have your ViewController class act as your UITableViewDataSource - from the Table View Programming Guide: " [t]he class creating the table view typically makes itself the data source and delegate by adopting the UITableViewDataSource and UITableViewDelegate protocols " (see this section ) 此外,除非有令人信服的理由,否则我还建议您让ViewController类充当UITableViewDataSource从《表视图编程指南》中:“ [创建表视图的类通常使自身成为数据源和委托通过采用UITableViewDataSource和UITableViewDelegate协议 ”(请参阅​​本

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM