2016-04-08 3 views
0

Я пытаюсь создать простое приложение списка контактов как средство обучения Swift. К сожалению, независимо от того, что я пытаюсь, я не могу отображать детали своих контактов в редактируемом текстовом поле на другом контроллере представления в виде таблицы (в котором содержатся основные контакты).Swift не позволяет мне устанавливать переменные данные

Вот блок кода, который должен быть влияющими на текстовые поля (я не уверен, что другой код на поставку)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "showDetail" { 
     if let indexPath = self.tableView.indexPathForSelectedRow { 
      let object = objects[indexPath.row] 
      let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController 
      print(object.firstName) 
      controller.fiName?.text = object.firstName 
      controller.laName?.text = object.lastName 
      controller.miName?.text = object.middleName 
      controller.aess?.text = object.address 
      controller.phoNumber?.text = object.phoneNumber 
      controller.yearBirth?.text = String(object.age) 
      print(controller.fiName) 
      controller.detailItem = object 
      controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem() 
      controller.navigationItem.leftItemsSupplementBackButton = true 
     } 
    } 

Результатом первой печатной линии, как я ожидаю, что это будет, который является именем контакта, но программа выходит из строя во второй печати с «EXC_BAD_INSTRUCTION»/фатальной ошибкой: неожиданно обнаружено нуль во время разворачивания и необязательного значения.

Почему я не могу установить controller.fiName? .text? Спасибо заранее за любую помощь.

+0

Вы еще не читали мой ответ? –

ответ

2

Я предполагаю, что ваш filName является UILabel или UITextField правильно?

Если вы проверяете свой код в DetailViewController вы заметите строку:

@IBOutlet weak var filName: UITextField! 

Вы видите ! в конце строки?

Это означает, что переменная (aka outlet) filName не может быть установлена ​​при инициализации, но будет установлена ​​в какой-то момент позже.

Теперь вы начинаете свой класс и пытаетесь получить доступ к этому свойству, которое еще не установлено при инициализации.

Чтобы обойти это, создайте экземпляр объекта в DetailViewController и установите этот экземпляр выбранному объекту, а затем установите свойства метки в функции viewDidLoad.

Что-то вроде этого:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "showDetail" { 
     if let indexPath = self.tableView.indexPathForSelectedRow { 
      let object = objects[indexPath.row] 
      let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController 
      controller.object = object 
     } 
} 

А потом в viewDidLoad из DetailViewController:

override viewDidLoad() { 
     fiName?.text = object.firstName 
     laName?.text = object.lastName 
     miName?.text = object.middleName 
     aess?.text = object.address 
     phoNumber?.text = object.phoneNumber 
     yearBirth?.text = String(object.age) 
     navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem() 
     navigationItem.leftItemsSupplementBackButton = true 
} 
+0

Вау! Спасибо большое за Ваш ответ. Когда я реализую код, как вы выложили, я все еще неожиданно нахожу нуль, разворачивая необязательное значение. Кроме того, кажется, что объект не передается должным образом, поскольку нет объекта object.firstName (но почему-то есть объект.middleName ??) –

+0

Я понял, простую и маленькую ошибку, я я вечно благодарен за вашу помощь, сэр! –

2

Вы устанавливаете текст ярлыка fiName слишком рано, где метка еще не выделена. Вместо этого пройдите через объект, а затем установите текст в viewDidLoad следующего контроллера.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "showDetail" { 
     if let indexPath = self.tableView.indexPathForSelectedRow { 
     let object = objects[indexPath.row] 
     let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController 

     //pass through object: 
     controller.object = object 

     print(object) 
    } 
} 

А затем в следующем ViewController viewDidLoad установить текст:

override viewDidLoad() { 
    //Now set the text value here: 
    fiName?.text = object.firstName 
} 
+0

Привет, Джо! Спасибо большое за Ваш ответ. Все ответы дали мне гораздо лучшее представление о том, что я пытался сделать.Извините, я не ответил на ваш ответ раньше, у меня была половина ответа, написанного и забывшего об этом :-) Всего наилучшего –

+0

Нет проблем @LiamS, было бы здорово, если бы вы смогли проголосовать/отметить его как принятое для меня. Надеюсь, я смогу помочь. –

1

объект Просто должен быть передан в prepareForSegue

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     if segue.identifier == "showDetail" { 
      if let indexPath = self.tableView.indexPathForSelectedRow { 
       let object = objects[indexPath.row] 
       let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController 
       controller.detailItem = object 
       controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem() 
       controller.navigationItem.leftItemsSupplementBackButton = true 
      } 
     } 
    } 

И тогда выходы должны быть установлены в viewDidLoad

class DetailViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     fiName?.text = detailItem.firstName 
     laName?.text = detailItem.lastName 
     miName?.text = detailItem.middleName 
     aess?.text = detailItem.address 
     phoNumber?.text = detailItem.phoneNumber 
     yearBirth?.text = String(detailItem.age) 
    } 
} 
Смежные вопросы