#swift #segue #ios8 #xcode6
#swift #segue #ios8 #xcode6
Вопрос:
Я передаю данные из контроллера табличного представления в подробное представление. Я попытался использовать indexPath.row
непосредственно в моем prepareForSegue
методе, однако он отображает ошибку
использование неразрешенного идентификатора ‘indexPath’
Итак, после поиска в Интернете я настроил переменную, indexOfSelectedPerson
которой присвоено значение indexPath.row
. Проблема при запуске приложения в симуляторе заключается в том, что prepareForSegue получает начальное значение indexOfSelectedPerson
(0), а затем получает значение выбранной строки только после того, как я щелкну по ней. Итак, когда я нажимаю кнопку «Назад» в симуляторе и выбираю другую строку, в подробном представлении отображается информация о строке, которую я выбрал в предыдущий раз.
import UIKit
class MasterTableViewController: UITableViewController {
var people = []
var indexOfSelectedPerson = 0
override func viewDidLoad() {
super.viewDidLoad()
people = ["Bob", "Doug", "Jill"]
}
override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {
return 1
}
override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
return people.count
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView!.dequeueReusableCellWithIdentifier("personCell", forIndexPath: indexPath) as UITableViewCell
cell.text = "(people[indexPath.row])"
return cell
}
override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!)
{
indexOfSelectedPerson = indexPath.row
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if let mySegue = segue.identifier {
if mySegue == "personDetails" {
let detailsVC: DetailTableViewController = segue.destinationViewController as DetailTableViewController
detailsVC.selectedPersonName = "(people[indexOfSelectedPerson])"
}
}
}
}
Итак, при выборе Doug при первом запуске приложения в симуляторе отображаются сведения о Bob, потому что indexPathOfSelectedPerson
равно 0. Нажатие кнопки «Назад», а затем выбор Jill отображает сведения о Doug, потому что indexPathOfSelectedPerson
стало 1, когда я нажал на Doug в предыдущий раз. Я предполагаю, что проблема связана с порядком, в котором вызываются методы.
Ответ №1:
Лучший способ сделать такого рода вещи — не использовать делегат.
Обновлен Swift 4
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let selectedIndex = tableView.indexPath(for: sender as! UITableViewCell)
// Do your stuff with selectedIndex.row as the index
}
Оригинальный ответ
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
let selectedIndex = self.tableView.indexPathForCell(sender as UITableViewCell)
// Do your stuff with selectedIndex.row as the index
}
Комментарии:
1. Добавленная вами строка выдала ошибку в Xcode, связанную с удалением AnyObject, и предложила изменить строку на: пусть SelectedIndex = self.TableView.indexPathForCell (отправитель как UITableViewCell). Это исправило ошибку. Я изменил indexOfSelectedPerson на SelectedIndex.row, как вы сказали, и все работает. Спасибо.
2. Именно то, что я искал. В Xcode 7 (Swift 2.2) вам нужно принудительно привести отправителя к
UITableViewCell
вот так:self.tableView.indexPathForCell(sender as! UITableViewCell)
3. если у меня разные типы ячеек пользовательского класса, то как я могу определить тип ячейки. Спасибо
Ответ №2:
Обновление Swift 3:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let selectedIndex = tableView.indexPath(for: sender as! UITableViewCell)!
// Do your actual preparing here...
}
Ответ №3:
//In didSelectRowAtIndexPath, you use this code:
func tableView(tvMain: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("yourSegueName", sender: nil)
}
//And prepareForSegue to get IndexPath and send your value
override func prepareForSegue(segue: UIStoryboardSegue,
sender: AnyObject!){
let indexPath : NSIndexPath = self.yourTableView.indexPathForSelectedRow()!
//make sure that the segue is going to secondViewController
let detailsVC = segue.destinationViewController as DetailTableViewController
detailsVC.selectedPersonName = "(people[indexPath.row])"
}