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



можно ли отменить переход в prepareForSegue: способ?



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

611   10  

10 ответов:

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

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

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

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

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

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

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

Swift 3: func shouldPerformSegue(идентификатор withIdentifier: строка, отправитель: есть?) -> Bool и

возвращаемое значение правда Если переход должен быть выполнен, или 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
}

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

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

его легко в swift .

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

    return true
}

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

- (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];
}

должен выполнить Segue для Регистра входа

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

    [self getDetails];

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

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

            _userNameTxtf.text=@"";
            _passWordTxtf.text=@"";

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

            [loginAlert show];

            _userNameTxtf.text=@"";
            _passWordTxtf.text=@"";

            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);

}

аналогично ответу каолина-оставить seque подключенным к элементу управления, но проверить элемент управления на основе условий в представлении. Если вы запускаете взаимодействие с ячейкой таблицы, вам также нужно установить свойство 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;
    }

}

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

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

Swift 4 Ответ:

Ниже приведена реализация Swift 4 для отмены segue:

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    if identifier == "EditProfile" {
        if userNotLoggedIn {
            // Return false to cancel segue with identified Edit Profile
            return false
        }
    }
    return true
}

Comments

    Ничего не найдено.