Предотвратить segue в методе prepareForSegue?

Можно ли отменить segue в методе prepareForSegue:?

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

Ответ 1

В iOS 6 и более поздних версиях это возможно: Вы должны реализовать метод

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender 

в вашем контроллере. Вы делаете свою проверку там, и если это нормально, тогда return YES;, если это не return NO;, а prepareForSegue не является вызовом.

Обратите внимание, что этот метод не вызывается автоматически при запуске segues программно, если вам нужно выполнить проверку, тогда вам нужно вызвать shouldPerformSegueWithIdentifier, чтобы определить, выполнять ли segue.

Ответ 2

Примечание: принятый ответ - лучший подход, если вы можете настроить iOS 6. Для таргетинга на iOS 5 этот ответ будет выполнен.

Я не считаю, что можно отменить segue в prepareForSegue. Я бы предложил перемещать вашу логику до такой степени, что сначала отправляется сообщение performSegue.

Если вы используете Interface Builder для подключения segue непосредственно к элементу управления (например, привязывая segue непосредственно к UIButton), вы можете выполнить это с небольшим количеством рефакторинга. Проведите переход к контроллеру представления вместо определенного элемента управления (удалите старую ссылку segue, а затем перетащите управление с самого контроллера представления на контроллер представления назначения). Затем создайте IBAction в вашем контроллере вида и подключите управление к IBAction. Затем вы можете сделать свою логику (проверить пустой TextField) в только что созданном вами IBAction и решить, будет ли программно performSegueWithIdentifier.

Ответ 3

В качестве альтернативы, это несколько плохое поведение, чтобы предложить кнопку, которую пользователь не должен нажать. Вы можете оставить сегмент подключенным к стенду, но начать с отключенной кнопки. Затем подключите UITextField "editChanged" к событию на элементе управления видом ala

- (IBAction)nameChanged:(id)sender {
    UITextField *text = (UITextField*)sender;
    [nextButton setEnabled:(text.text.length != 0)];
}

Ответ 4

Его легко в быстром.

override func shouldPerformSegueWithIdentifier(identifier: String,sender: AnyObject?) -> Bool {

    return true
}

Ответ 5

Как сказал Авраам, проверить правильность или нет в следующей функции.

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender
{
     // Check this identifier is OK or NOT.
}

И, вызов performSegueWithIdentifier:sender:, вызываемый программированием, может быть заблокирован путем перезаписи следующего метода. По умолчанию он не проверяет правильность или не на -shouldPerformSegueWithIdentifier:sender:, мы можем сделать это вручную.

- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    // Check valid by codes
    if ([self shouldPerformSegueWithIdentifier:identifier sender:sender] == NO) {
        return;
    }

    // If this identifier is OK, call `super` method for `-prepareForSegue:sender:` 
    [super performSegueWithIdentifier:identifier sender:sender];
}

Ответ 6

Swift 3: func shouldPerformSegue (с идентификатором идентификатора: String,                отправитель: любой?) → Bool

Возвращаемое значение true, если нужно выполнить segue или false, если его следует игнорировать.

Пример:

var badParameters:Bool = true

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    if badParameters  {
         // your code here, like badParameters  = false, e.t.c
         return false
    }
    return true
}

Ответ 7

Должен выполнить Segue для регистрации в системе

-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{

    [self getDetails];

    if ([identifier isEqualToString:@"loginSegue"])
    {

        if (([_userNameTxtf.text isEqualToString:_uname])&&([_passWordTxtf.text isEqualToString:_upass]))
        {

            [email protected]"";
            [email protected]"";

            return YES;
        }
        else
        {
            UIAlertView *loginAlert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Invalid Details" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:nil];

            [loginAlert show];

            [email protected]"";
            [email protected]"";

            return NO;
        }

    }

    return YES;

}

-(void)getDetails
{
    NSArray *dir=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *dbpath=[NSString stringWithFormat:@"%@/userDb.sqlite",[dir lastObject]];

    sqlite3 *db;

    if(sqlite3_open([dbpath UTF8String],&db)!=SQLITE_OK)
    {
        NSLog(@"Fail to open datadbase.....");
        return;
    }

    NSString *query=[NSString stringWithFormat:@"select * from user where userName = \"%@\"",_userNameTxtf.text];

    const char *q=[query UTF8String];

    sqlite3_stmt *mystmt;

    sqlite3_prepare(db, q, -1, &mystmt, NULL);

    while (sqlite3_step(mystmt)==SQLITE_ROW)
    {
        _uname=[NSString stringWithFormat:@"%s",sqlite3_column_text(mystmt, 0)];

        _upass=[NSString stringWithFormat:@"%s",sqlite3_column_text(mystmt, 2)];
    }

    sqlite3_finalize(mystmt);
    sqlite3_close(db);

}

Ответ 8

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

Например, у меня есть форма в сгруппированном представлении таблицы. Одна из ячеек приводит к другому tableView, который действует как сборщик. Всякий раз, когда элемент управления изменяется в главном представлении, я вызываю этот метод

-(void)validateFilterPicker
{
    if (micSwitch.on)
    {
        filterPickerCell.textLabel.enabled = YES;
        filterPickerCell.detailTextLabel.enabled = YES;
        filterPickerCell.userInteractionEnabled = YES;
        filterPickerCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    else
    {
        filterPickerCell.textLabel.enabled = NO;
        filterPickerCell.detailTextLabel.enabled = NO;
        filterPickerCell.userInteractionEnabled = NO;
        filterPickerCell.accessoryType = UITableViewCellAccessoryNone;
    }

}

Ответ 9

Другой способ - переопределить метод tableView с помощью willSelectRowAt и вернуть нуль, если вы не хотите показывать segue. showDetails() - это некоторый bool. В большинстве случаев это должно быть реализовано в модели данных, представленной в ячейке с помощью indexPath.

 func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        if showDetails() {
                return indexPath            
        }
        return nil
    }