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

ios cocoa-touch uiviewcontroller storyboard segue

92285 просмотра

10 ответа

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

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

Автор: Shmidt Источник Размещён: 12.11.2019 09:14

Ответы (10)


480 плюса

Решение

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

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

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

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

Автор: Abraham Размещён: 10.10.2012 11:34

52 плюса

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

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

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

Автор: Mike Mertsock Размещён: 09.11.2011 02:49

16 плюса

Swift 3 : func shouldPerformSegue (withIdentifier identifier: String, sender: Any?) -> Bool

Возвращаемое значение true, если следует выполнить переход, или 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
}
Автор: OrdoDei Размещён: 30.09.2016 01:53

12 плюса

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

- (IBAction)nameChanged:(id)sender {
    UITextField *text = (UITextField*)sender;
    [nextButton setEnabled:(text.text.length != 0)];
}
Автор: Kaolin Fire Размещён: 25.11.2011 12:31

11 плюса

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

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

    return true
}
Автор: Zumry Mohamed Размещён: 27.10.2015 03:49

9 плюса

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

- (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];
}
Автор: AechoLiu Размещён: 30.11.2015 08:03

5 плюса

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

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

}
Автор: Swappyee Размещён: 06.07.2015 07:47

4 плюса

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

}
Автор: James Moore Размещён: 30.08.2012 04:46

4 плюса

Swift 4 Ответ:

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

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
}
Автор: Pankaj Kulkarni Размещён: 10.07.2018 03:58

2 плюса

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

 func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        if showDetails() {
                return indexPath            
        }
        return nil
    }
Автор: Bogdan Ustyak Размещён: 10.02.2017 02:37
Вопросы из категории :
32x32