Подтвердить что ты не робот

Как "отменить" UIStoryBoardSegue

Кто-нибудь знает, как "остановить" переход segue условно:

Мои ячейки представления таблицы представляют собой продукты, которые можно просмотреть в подробном "подробном" представлении... или не могут! (Это зависит от нескольких вещей)

Теперь мое приложение считает, что все продукты "разблокированы":

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
    ListaProdottiController *prodottiViewController = [segue destinationViewController];
    prodottiViewController.blocco = [self.fetchedResultsController objectAtIndexPath:selectedRowIndex];
}

Как я могу отменить выбор строки = > развертка, в этот момент?

4b9b3361

Ответ 1

Если вы ориентируетесь на iOS 6 или выше, то мои знания самого чистого способа сделать это следующие:

-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    if([identifier isEqualToString:@"show"])
    {
        NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
        Blocco *blocco = [self.fetchedResultsController objectAtIndexPath:selectedRowIndex];
        return [blocco meetRequiredConditions];
    }
    return YES;
}

Если существует метод

-(BOOL) meetsRequiredConditions;

Определенный в вашем классе Blocco возвращает YES, если допустимы "пара вещей", которые разрешают детализацию.

Ответ 2

Я не знаю, правильно ли это сделать, но я обнаружил обходной путь.

Из раскадровки я связываю (control + click) segue из строки состояния в контроллере представления. Дайте segue идентификатор (например: switchSegue).

Теперь, из действия в вашем коде (в моем коде я использую кнопку), я вызываю:

 [self performSegueWithIdentifier:@"switchSegue" sender:sender];

Таким образом, вы можете контролировать, выполняется ли ваш segue или нет. Попробуйте учебники, которые помогли мне от здесь и здесь

Надеюсь, что это поможет.

Ответ 3

Я использую гораздо более простой и аккуратный подход.

Раскадровка

  • Создайте две идентичные ячейки с разными идентификаторами. Например: "cellWithSegue" и "cellWithoutSegue".
  • Подключите первую ячейку ( "cellWithSegue" ) с помощью сегмента, который вы хотите отобразить.
  • Не соединяйте вторую ячейку с любым сегментом.

Просмотр таблицы

  • На cellForRowAtIndexPath реализует логику, чтобы определить, должна ли ячейка быть связана с segue или нет.
  • Для ячеек, которые должны быть связаны с segue, используйте идентификатор "cellWithSegue" , а для остальных - "cellWithoutSegue".

Этот способ выглядит намного проще для реализации, а также не изменяет способ работы segues.

Ответ 4

Возможно, я ошибаюсь, но после того, как я боролся с этим, я просто отключил взаимодействие пользователя соты в ячейках, где я не хотел, чтобы сработала кнопка (в cellForRowAtIndexPath:). Кажется, отлично работает, и это всего лишь 1 строка кода!

cell.userInteractionEnabled = NO;

Ответ 5

Самое простое решение - создать ручную секцию в доске объявлений и использовать ее, как показано ниже.

[self performSegueWithIdentifier:@"loginSuccessSegue" sender:self];

Или


@Fabio: Я пытался получить решение для подобных случаев, и я почти нашел решение.

Использование футляры 1. Остановить переход segue условно 2. Измените целевой режим viewController

Решение:

Используйте "Custom" segue. Следуйте инструкциям ниже, чтобы создать Custom segue 1. Создайте подкласс UIStoryboardSegue "MyCustomSegue.h"

@interface MyCustomSegue : UIStoryboardSegue
@end

"MyCustomSegue.m"

Отменить initWithIdentifier для реализации прецедентов 1 и 2 Если вы вернете нуль, segue будет отменен/никаких действий не будет предпринято Вы создаете экземпляр своего ViewController и устанавливаете его как пункт назначения. Вы также можете указать место назначения как старый файл xib.. этот код прокомментирован, но я гарантировал, что он будет работать.

@implementation MyCustomSegue
- (id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination{

    UIStoryboard *storyBoard= [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];

    UIViewController *viewController = [storyBoard instantiateViewControllerWithIdentifier:@"testIdentifier"];

    // MyViewController* viewController= [[MyViewController alloc]initWithNibName:@"MyViewController" bundle:nil];
    return [super initWithIdentifier:identifier source:source destination:viewController];
}
  1. Вы должны переопределить "выполнить".

Здесь также можно использовать прецедент 1.

- (void)perform {
    // if either source or destination is nil, stop
    if (nil == self.sourceViewController || nil == self.destinationViewController) return;
    // return; //No Action. Segue will be cancelled
    UINavigationController *ctrl = [self.sourceViewController navigationController];
    [ctrl
     pushViewController:self.destinationViewController
     animated:YES];
}

Надеюсь, это поможет. Plz напишите, если вы не поняли.

Ответ 6

Хороший и легкий способ сделать это внутри метода UITableViewDelegate tableView:willSelectRowAtIndexPath: - применимо. YMMV.

Вот как я это делаю (iOS 5, ARC). Я использую переменную экземпляра BOOL в моем контроллере представления, изначально установленную в False в viewDidLoad. Контроллер представления назначения, который ячейки таблицы настроены для перехода в Интерфейсный Builder, полагается на бит данных, загруженных с сервера, поэтому я не хочу, чтобы segue выполнялся до тех пор, пока у меня не будет данных.

Упрощенный, это выглядит так:

@implementation SomeViewController {
    BOOL okayToSegue;
}

...

- (void)viewDidLoad
{
    [super viewDidLoad];
    okayToSegue = NO;
    // The success block for the data retrieval
    void(^successBlock)(void) = ^{
        // Other code...
        okayToSegue = YES;
    }
    [[ServerClient sharedClient] getDataFromServerSuccess:successBlock];
}

...

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (!okayToSegue) {
        return nil;
    }
    return indexPath;
}

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

Возврат nil в tableView:willSelectRowAtIndexPath: вызывает нажатие на ячейку таблицы, чтобы ничего не делать. Только после того, как я получил слово из моего экземпляра AFHTTPClient (через successBlock), что данные, которые нужно просмотреть, чтобы просмотреть требования к контроллеру, готовы и ждут, я изменяю переменную экземпляра, и будущие краны будут работать нормально. В реальном коде вы хотите иметь видимое пользователем уведомление или визуально явный контрольный знак, что segueing еще не возможно.

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

Ответ 7

Как шаблон Apple делает это для iPad popOver, используя ручной режим, в отличие от автоматического перехода, который срабатывает при нажатии ручного устройства, с помощью функции performSegueWithIdentifier:

Чтобы создать ручной segue вместо ctrl-перетаскивания из элемента, который вы имеете в виду, ctrl-drag из значка контроллера View, установите идентификатор для segue, и вы закончите в IB.

manual segues

Ответ 8

Здесь другое решение, которое я только что нашел.

В вашем Mainstoryboard TableView, когда вы используете автоматический переход из вашей ячейки (идентификатор = ячейка) в представление назначения, вы также можете добавить другую ячейку с другим идентификатором (идентификатор = CellWithoutSegue). Поэтому при создании новой ячейки в cellForRowAtIndexPath просто повторно используйте идентификатор ячейки, который вы хотите (с или без segue).

Надеюсь, что это поможет!

(Скажите, хотите ли вы примеры кода кода).

Привет,

Ответ 9

В вашем методе - (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender; вы можете добавить некоторый код, например:

if ([[segue identifier] isEqualToString:@"DemoSegue"] && !self.canOpenDemo) {
    id *nc = [segue destinationViewController]; // UIViewController, UINavigationController, etc. (keeping "id" will return warning)
    [nc dismissModalViewControllerAnimated:NO];
}

И это остановит просмотр от открытия, однако я не проверил, но похоже, что он уже вызвал бы ваш контроллер назначения назначения инициализации функции (опять же, я не проверял в Xcode, поэтому я не полностью уверен).