目前正在使用两个视图控制器和一个处理商店详细信息的swift文件,例如电话号码。有一个主ViewController和一个DetailsViewController。
我目前从google places 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
}
答案 0 :(得分:0)
您需要在placeDetails
中将prepareForSegue
分配给目标视图控制器。我知道你不是这样做的,因为你创建了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
是一个更好的地方。
答案 1 :(得分:-1)
尝试将phoneNumber转换为字符串。
detailsVC.phoneNumberLabel.text = String(placeDetails.phoneNumber!)
此外,nil值可能来自API响应的编码方法。
编辑
我认为您必须在UILabel
的{{1}}方法中设置viewDidLoad()
的文字。在showDetailsVC
中声明string
变量,然后将showDetailVC
变量传递给刚刚声明的字符串。 (而不是直接在placeDetails.phoneNumber
方法中设置文本)。然后在你的
showDetailVC将文本设置为tapLabel()