it-swarm.com.ru

Условный переход выполняется при нажатии на UITableViewCell

Я работаю над проектом для iOS 5 с использованием Xcode 4.2. У меня есть один UITableViewController и я хочу выполнить переход, когда пользователь нажимает на ячейку таблицы, но целевой контроллер представления зависит от действий, выполненных в этой ячейке. Например, когда пользователь нажимает на ячейку, я хотел бы загрузить SomeViewController, но когда пользователь нажимает на эту же ячейку в режиме редактирования, я хотел бы загрузить AnotherViewController. К сожалению, в сборщике раскадровок Xcode 4.2 нет способа настроить несколько сегментов в одной ячейке, или я просто не понимаю. Возможно, есть способ создать переход вручную, в редакторе кода. Обычно я хочу предоставить пользователю способ «ввести» элемент, представленный ячейкой, с помощью одного контроллера представления, и «отредактировать» элемент, представленный той же ячейкой, с помощью другого контроллера представления. Хотя переключение на второй контроллер представления (редактор) только в режиме редактирования таблиц было моим первым, но, возможно, есть лучший способ. Любая помощь будет оценена.

39
Darrarski

Просматривая раскадровку, перетащите ее из исходного контроллера вида на контроллер вида назначения. Это создаст переход, который вы можете запустить программно прямо из вашего исходного View Controller. Убедитесь, что вы дали Segue имя. Это имя, которое вы передадите в executeSegue: withIdentifier: метод исходного контроллера представления.

54
Lemont Washington

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

  1. в клетке обнаружено прикосновение
  2. передача выполнена

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

Теперь, если вы хотите условно segue, то (как уже упоминалось в других ответах) вы удаляете этот segue и создаете новый из UITableViewController (перетащите его из навигатора объектов, а не раскадровки) на следующий контроллер - и дать ему имя.

Затем - и это та часть, которую мне не хватало - внедрите tableView:didSelectRowAtIndexPath в свой контроллер табличного представления, чтобы выполнить переход программно и условно, как показано ниже.

Обратите внимание, что вам также необходимо как-то идентифицировать свою ячейку, чтобы знать, была ли выбрана интересующая вас ячейка. Вы могли бы сделать это, зная путь индекса в статической таблице, но я предпочитаю устанавливать уникальный идентификатор моих ячеек в IB (даже если он не нужен для удаления из очереди, поскольку это статическая таблица) и проверять его. Таким образом, если я переместлю свою ячейку вверх или вниз в статической таблице, мне не нужно будет менять этот код.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Find the selected cell in the usual way
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    // Check if this is the cell I want to segue from by using the reuseIdenifier
    // which I set in the "Identifier" field in Interface Builder
    if ([cell.reuseIdentifier isEqualToString:@"CellIWantToSegueFrom"]) {

    // Do my conditional logic - this was the whole point of changing the segue
    if (myConditionForSegueIsSatisfied) {
        // Perform the segue using the identifier I was careful to give it in IB
        // Note I'm sending the cell as the sender because that's what the normal
        // segue does and I already had code counting on that
        [self performSegueWithIdentifier:@"SegueIdentifer" sender:cell];
    }
}

Обратите внимание, как я отправляю ячейку с segue - это делает нормальный segue из ячейки, и я изначально передал nil, и мой код, который зависел от него, перестал работать.

33
Rhubarb

Это старый вопрос и некоторые отличные правильные ответы но я опубликую некоторую дополнительную информацию, которая мне показалась полезной, когда я столкнулся с этим:

  1. Если вы создаете переход в раскадровке путем перетаскивания ctl + из SomeVC в AnotherVC, удалите его. 

  2. В навигаторе объектов ctl + перетащите на уровне ViewController (обычно сначала в иерархии под именем VC) из SomeVC в AnotherVC. Дайте seue уникальный идентификатор.

  3. Реализуйте tableView: didSelectRowAtIndexPath:, как описано выше.

  4. Я нашел полезным использовать оператор switch в tableView: didSelectRowAtIndexPath:

    switch (indexPath.row) {
    case 0:
        [self performSegueWithIdentifier:@"yourIDHere" sender:self];
        break;
    case 1:
        // enter conditional code here...
        break;
    case 2:
        // enter conditional code here...
        break;
    // ... for however many cells you require
    
    default:
        break;
    

    }

Спасибо всем за отличные ответы.

5
Chris Holloway

Вы можете легко контролировать открытие любого перехода в своем пользовательском UIViewController, реализуя:

override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool { return true // or false, depending on what you need }

0
vedrano