属性值打印,但当分配给标签时,它显示 nil



当前使用两个视图控制器和一个处理商店详细信息(如电话号码)的快速文件。有一个主视图控制器和一个详细信息视图控制器。

我目前从谷歌地点 api 获取数据,并能够成功地将值存储在 PlaceDetails 类中。 测试数据 - 我可以打印到控制台。但是,当我尝试将从 API 获取的值分配给 UILabel 时,应用程序崩溃并显示该属性的值为 nil。我不确定为什么会这样。我觉得在两个视图控制器中,我正确地实例化了 PlaceDetails 类并正确访问了它的属性,但我不知道有些事情出了问题。

class ViewController: UIViewController
{
   let placeDetails = PlaceDetails()
   let detailsVC = DetailsViewController()
   func tapLabel( sender: UITapGestureRecognizer )
   {
    // print statement successfully prints out the stored value as - Optional("1 888-555-5555")
    print(placeDetails.phoneNumber)
    // assigning value to label causes a crash stating value is nil
    detailsVC.phoneNumberLabel.text = placeDetails.phoneNumber!
    self.performSegueWithIdentifier("showDetailsVC", sender: self)
   }
}
class DetailsViewController: UIViewController
{
    @IBOutlet weak var phoneNumberLabel  : UILabel!
    let placeDetails = PlaceDetails()
    override func viewDidLoad()
    {
       super.viewDidLoad()
       //This approach does not cause a crash but outputs nil to the console for both the print statement and the assignment statement
       print(placeDetails.phoneNumber)
       phoneNumberLabel.text = placeDetails.phoneNumber! 
    }  
}
class PlaceDetails
{
     override init()
     {
         super.init()
     }
     var phoneNumber : String? //viewcontroller actions give this class property its value
}
您需要

prepareForSegue中将placeDetails分配给目标视图控制器。我知道您没有这样做,因为您已经将placeDetails创建为let常量而不是变量,因此它永远不会从您最初分配的空PlaceDetails更改。

您应该将其声明为可选变量,然后在使用它时正确解包;

class ViewController: UIViewController
{
    let placeDetails = PlaceDetails()
    func tapLabel( sender: UITapGestureRecognizer )
    {
        self.performSegueWithIdentifier("showDetailsVC", sender: self)
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if (segue.identifier == "showDetailsVC") {
            let destVC = segue.destinationViewController as! DetailsViewController
            destVC.placeDetails = self.placeDetails
        }
    }
}
class DetailsViewController: UIViewController
{
    @IBOutlet weak var phoneNumberLabel  : UILabel!
    var placeDetails: PlaceDetails?
    override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        if let placeDetails = self.placeDetails {
            if let phoneNumber = placeDetails.phoneNumber {
                self.phoneNumberLabel.text = phoneNumber
            }
        }
    }
}

不能在viewDidLoad中使用值,因为此方法将在设置属性之前执行;视图控制器在调用prepareForSegue之前加载,因此viewWillAppear位置更好。

尝试将您的电话号码转换为字符串。

detailsVC.phoneNumberLabel.text = String(placeDetails.phoneNumber!)

此外,nil 值可能来自 API 响应的编码方法。

编辑

我认为您必须以showDetailsVCviewDidLoad()方法设置UILabel的文本.在 showDetailVC 中声明一个 string 变量,然后将placeDetails.phoneNumber变量传递给刚刚声明的字符串。(而不是直接在 tapLabel() 方法中设置文本)。然后在你的showDetailVC 在viewDidLoad()中将文本设置为您的 UILabel

相关内容

  • 没有找到相关文章