it-swarm.com.ru

Нажмите Segue от UITableViewCell для ViewController в Swift

Я столкнулся с проблемами с моими UITableViewCells. Я подключил свой UITableView к API для заполнения своих ячеек. 

Затем я создал функцию, которая захватывает indexPath.row, чтобы определить, какой JSON-объект внутри массива должен быть отправлен в RestaurantViewController

Ссылка на мой проект Xcode для облегчения отладки и решения проблем

Вот как выглядит мой маленький фрагмент для установки «щелчков строк» ​​в глобальной переменной.

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
     i = indexPath.row
}

А вот моя функция prepareForSegue(), которая должна подключить мой Push-переход к RestaurantViewController.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "toRestaurant"{
    let navigationController = segue.destinationViewController as UINavigationController
    let vc = navigationController.topViewController as RestaurantViewController
    vc.data = currentResponse[i] as NSArray
 }
}

И вот как я настроил свой переход от UITableViewCell

Вот мой результат, я попытался щелкнуть по каждой из этих ячеек, но я не буду перемещен в другой viewController ... У меня также нет ошибки. Что здесь не так?

Испытанные решения, которые не будут работать

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if segue.identifier == "toRestaurant"{
            let vc = segue.destinationViewController as RestaurantViewController
            //let vc = navigationController.topViewController as RestaurantViewController
            vc.data = currentResponse[i] as NSArray
        }
    }
11
Jack

Проблема в том, что вы неправильно обрабатываете свои данные . Если вы посмотрите на свой массив currentResponse, вы увидите, что он содержит NSDictionaries, но в вашем prepareForSegue вы попытаетесь привести NSDictionary к NSArray, что сделает сбой приложения.

Измените переменную data в RestaurantViewController на NSDictionary и измените свой prepareForSegue, чтобы передать NSDictionary

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if let cell = sender as? UITableViewCell {
        let i = redditListTableView.indexPathForCell(cell)!.row
        if segue.identifier == "toRestaurant" {
            let vc = segue.destinationViewController as RestaurantViewController
            vc.data = currentResponse[i] as NSDictionary
        }
    }
}
20
ergoon

Следующие шаги должны решить вашу проблему. Если нет, пожалуйста, дайте мне знать.

  1. Удалите свою реализацию tableView(tableView, didSelectRowAtIndexPath:).

  2. Сделайте data для RestaurantViewController типа NSDictionary!

  3. Определите выбранную строку в prepareForSegue:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if let cell = sender as? UITableViewCell {
            let i = tableView.indexPathForCell(cell)!.row
            if segue.identifier == "toRestaurant" {
                let vc = segue.destinationViewController as RestaurantViewController
                vc.data = currentResponse[i] as NSDictionary
            }
        }
    }
    
4
Tammo Freese

Dropbox ссылка на каталог stack3

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

  2. Программа имитирует то, что у вас есть (насколько я понял). Table Controller 1 переходит к Table Controller 2 из ячейки таблицы. У меня не было проблем с переходом. Обратите внимание, что у меня нет ни необходимости, ни дополнения сборника рассказов, чтобы начать переход. 

  3. Я встроил оба контроллера в контроллеры навигации. Мой опыт показывает, что это экономит много усилий для настройки навигации.

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

  5. Я использовал глобальную переменную (selectedRow), хотя это не рекомендуемая практика. Но вы так же легко используете prepareForSegue для установки переменной в RestaurantTableViewController (я покажу пример)

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

К сожалению, я просто не могу получить код правильно

import UIKit

var selectedRow = -1

class TableViewController: UITableViewController {

var firstArray = ["Item1","Item2","Item3","Item4"]

override func viewDidLoad() {

super.viewDidLoad()

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return firstArray.count

}


let nameOfCell = "RestaurantCell"

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell

cell.textLabel!.text = firstArray[indexPath.row]

return cell

}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

selectedRow = indexPath.row

}

// MARK: - Navigation

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

let vc = segue.destinationViewController as RestaurantTableViewController

// can write to variables in RestaurantTableViewController if required

vc.someVariable = selectedRow

}


}


import UIKit

class RestaurantTableViewController: UITableViewController {

var secondArray = ["Item 2.1", "Item 2.2", "Item 2.3", "Item 2.4"]

var someVariable = -1

override func viewDidLoad() {

super.viewDidLoad()

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

return 1

}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return secondArray.count

}

let nameOfCell = "RestaurantCell"

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell

cell.textLabel!.text = secondArray[indexPath.row]

if indexPath.row == selectedRow {

cell.textLabel!.text = cell.textLabel!.text! + " SELECTED"

}

return cell

}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

selectedRow = indexPath.row

}

}
3
Syed Tariq

Я заметил, что на вашем скриншоте вашей раскадровки сцена соединяет первую ячейку прототипа с RestaurantViewController. Эта ячейка-прототип выглядит как ячейка в «базовом» стиле с аксессуаром индикатора раскрытия справа. Но посмотрите на скриншот запущенного приложения. Таблица заполняется ячейками, которые выглядят как ячейка в стиле «Субтитры» без аксессуара индикатора раскрытия справа.

Причина того, что ваш segue никогда не запускается, независимо от того, что вы делаете, заключается в том, что segue настроен только для работы с конкретной ячейкой прототипа, но эта ячейка прототипа никогда не используется при заполнении таблицы. Что бы вы ни делали в tableView:cellForRowAtIndexPath:, вы не используете нужную ячейку прототипа.

У @Starscream правильная идея: выгрузить нужную ячейку с правильным идентификатором и сопоставить его с идентификатором ячейки-прототипа в Интерфейсном Разработчике. Сбой, который вы получаете даже после этого, может быть из-за предыдущей проблемы, упомянутой в комментариях выше. Ваш переход в раскадровке явно указывает на UITableViewController. Ваш код в prepareForSegue:sender: должен быть let vc = segue.destinationViewController as RestaurantViewController, если RestaurantViewController является подклассом UITableViewController. Вы потерпите крах, если попытаетесь разыграть его как UINavigationController. Также убедитесь, что класс назначения UITableViewController в раскадровке указан как RestaurantController на панели Identity Inspector. Вы потерпите крах, если ваша программа скомпилирует, думая, что раскадровка просто содержит общий UITableViewController

Возвращаясь к исходной проблеме больше, я не знаю, как вы реализовали tableView:cellForRowAtIndexPath:, что может иметь решающее значение. Может быть, это не так просто. Возможно, вы планируете обрабатывать много ячеек-прототипов или генерировать пользовательские ячейки во время выполнения. В этом случае один из способов сделать это проще для вас - программно выполнить переход, когда пользователь нажимает на ячейку. Вместо использования определенной ячейки прототипа, сделайте segue соединением, исходящим из UITableViewController Restauranger nära mig, идущим к RestaurantViewController. (Соединитесь в Интерфейсном Разработчике, перетаскивая управляющий щелчок от значка Контроллера Табличного представления в верхней части первого до тела второго). Чтобы сделать это полезным, вы должны присвоить этой последовательности идентификатор на панели инспектора атрибутов. Допустим, это "toRestaurant". Затем в конце вашего метода tableView:didSelectRowAtIndexPath: поместите эту строку кода: self.performSegueWithIdentifier("toRestaurant", sender: self). Теперь независимо от того, какая ячейка выбрана в таблице, эта сессия всегда будет срабатывать для вас.

2
Christopher Whidden

Я иду по прихоти здесь, так как я только сейчас вхожу в Свифт, но способ, которым я делаю это в своей prepareForSegue(), выглядит примерно так:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "toRestaurant"{
        let navigationController = segue.destinationViewController as UINavigationController
        let vc = navigationController.topViewController as RestaurantViewController
        //notice I changed [i] to [index!.row]
        vc.data = currentResponse[index!.row] as NSArray
     }
    }

Для меня это выглядит так: вы вызываете переменную i, которая похожа на приватную переменную внутри метода вашего класса. Вы можете сделать что-то вроде @Syed Tariq с переменной selectRow и установить ее выше своего class SomeController: UIViewController /*, maybe some more here? */ {, а затем подписать переменную внутри вашего

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    selectedRow = indexPath.row

}

метод, как указано выше, но оба способа должны работать довольно хорошо.

1
KyleMassacre

Попробуйте создать такие клетки в вашем методе cellForRow:

let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MyTestCell", forIndexPath: indexPath)
1
Starscream

У меня была та же проблема, и я нашел решение:

executeSegueWithIdentifier ("toViewDetails", отправитель: self)

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var cellnumber = procMgr.processos[indexPath.row].numero
    println("You selected cell #\(indexPath.row)")
    println(cellnumber)
    performSegueWithIdentifier("toViewDetails", sender: self)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "toViewDetails" {
         let DestViewController : ViewDetails = segue.destinationViewController as! ViewDetails
    }
}
0
João Henrique

Возможно, вам потребуется получить индекс выбранной ячейки UItableview. В приведенном ниже коде используется индекс выбранной ячейки (UItableview.indexPathForSelectedRow), чтобы получить правильный элемент массива.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "seguaVisitCardDetial" {
        let viewController = segue.destinationViewController as! VCVisitCardDetial
        viewController.dataThisCard =   self.listOfVisitCards[(tblCardList.indexPathForSelectedRow?.row)!]
    }
}
0
Chamath Jeevan