Переменная возвращает значение nil после изменения ее значения из другого файла swift - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь изменить значение переменной из другого файла Swift, но по какой-то причине он не работает и возвращает ноль.

Вот что я пробовал:

class ShowIssues: UIViewController, UITableViewDataSource, UITableViewDelegate {
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let si = self.storyboard?instantiateViewController(withIdentifier: "ShowIssueDetail") as! ShowIssueDetail
    si.idSelected = indexPath.row //Here I change the value of the variable
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
  }
}

ShowIssueDetail.swift:

class ShowIssueDetail: UITableViewController {
  var idSelected: Int! //This is the variable I want to change its value from the another swift file
    override func viewDidLoad() {
      print(idSelected) //Here it prints out nil instead of the selected row
    }
}

Я тоже так пробовал, но та же проблема:

class ShowIssues: UIViewController, UITableViewDataSource, UITableViewDelegate {
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let si = ShowIssueDetail()
    si.idSelected = indexPath.row //Here I change the value of the variable
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
  }
}

Что я делаю не так?

Заранее спасибо!

Примечание. Оба файла swift имеют различный тип, ShowIssues.swift - это UIViewController, а ShowIssueDetail - UITableViewController, я не знаю, не работает ли он из-за этого.

Ответы [ 4 ]

0 голосов
/ 07 ноября 2018

Ваш подход здесь неверен:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let si = self.storyboard?instantiateViewController(withIdentifier: "ShowIssueDetail") as! ShowIssueDetail
    si.idSelected = indexPath.row //Here I change the value of the variable
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
}

Вы создаете другой экземпляр VC и устанавливаете значение. Этот VC не тот, который будет показан.

Вам необходимо использовать prepareForSegue метод

var selectedRow: someTypeSameAsRow?

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    selectedRow = indexPath.row
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowIssueDetail",
        let vc = segue.destination as? ShowIssueDetail {
        vc.idSelected = selectedRow
    }
}

EDIT:

Чтобы устранить ошибку, упомянутую в комментариях, возможно, потребуется подождать, пока представление сведений будет загружено правильно. Функция awakeFromNib должна работать здесь:

// this goes in the view controller
override func awakeFromNib() {
    super.awakeFromNib()

    self.detailView.selected = selected
}

Итак, с этим кодом вы ждете, пока представление VC и его подпредставления не будут полностью загружены, а затем устанавливаете выбранное свойство showDetailView в то же выбранное свойство, которое находится в VC.

0 голосов
/ 07 ноября 2018

performSegue создаст новый экземпляр ShowIssueDetail.

Из-за этого вы никогда не устанавливаете idSelected

0 голосов
/ 07 ноября 2018

Похоже, вы говорите о переменной idSelected в вашем ShowIssueDetail контроллере представления.

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

Вам необходимо использовать prepareForSegue для передачи переменной в контроллер представления, к которому вы обращаетесь.

//Add an instance variable to remember which item is selected.
var selected: Int? 

class ShowIssues: UIViewController, UITableViewDataSource, UITableViewDelegate {
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    selected = self.storyboard?instantiateViewController(withIdentifier: "ShowIssueDetail") as! ShowIssueDetail
    performSegue(withIdentifier: "ShowIssueDetail", sender: self)
  }
}

func prepare(for: segue, sender: Any) {
   if let dest = segue.destination as? ShowIssueDetail {
     dest.idSelected = selected
   }
}
0 голосов
/ 07 ноября 2018

Если у вас настроен переход в Storyboard, вы не должны создавать экземпляр конечного контроллера представления из кода, раскадровка создаст для вас контроллер представления. Инициализируя другой экземпляр, вы в конечном итоге устанавливаете значения для экземпляра, который не будет представлен пользователю.

Вам необходимо переопределить prepare(for:) и установить значение там.

class ShowIssues: UIViewController, UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "ShowIssueDetail", sender: indexPath.row)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowIssueDetail", let destinationVC = segue.destination as? ShowIssueDetail, let selectedId = sender as? Int {
          destinationVC.idSelected = selectedId
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...