Respostas:
É possível no iOS 6 e posterior: você precisa implementar o método
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
No seu controlador de exibição. Você faz sua validação lá e, se estiver tudo bem, return YES;
se não estiver, return NO;
e o prepareForSegue não será chamado.
Observe que esse método não é chamado automaticamente quando o acionamento segue programaticamente. Se você precisar executar a verificação, precisará chamar shouldPerformSegueWithIdentifier para determinar se deve executar segue.
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
Nota: a resposta aceita é a melhor abordagem se você puder segmentar o iOS 6. Para segmentar o iOS 5, esta resposta será adequada.
Não creio que seja possível cancelar uma sequência prepareForSegue
. Eu sugeriria mover sua lógica ao ponto em que a performSegue
mensagem foi enviada pela primeira vez.
Se você estiver usando o Interface Builder para conectar um segue diretamente a um controle (por exemplo, vinculando um segue diretamente a um UIButton
), poderá fazer isso com um pouco de refatoração. Conecte as segue ao controlador de exibição em vez de um controle específico (exclua o link antigo segue e arraste com o controle do próprio controlador de exibição para o controlador de exibição de destino). Em seguida, crie um IBAction
no seu controlador de exibição e conecte o controle ao IBAction. Em seguida, você pode fazer sua lógica (verifique se há TextField vazio) no IBAction que você acabou de criar e decidir lá se deve ou não performSegueWithIdentifier
programaticamente.
Swift 3 : func shouldPerformSegue (com identificador de identificador: String, sender: Any?) -> Bool
Valor de retorno true se o segue deve ser executado ou false se deve ser ignorado.
Exemplo :
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
}
Como alternativa, é um comportamento um pouco ruim oferecer um botão que o usuário não deve pressionar. Você pode deixar os seguimentos conectados como suportes, mas comece com o botão desativado. Em seguida, conecte "editChanged" do UITextField a um evento no controle de exibição ala
- (IBAction)nameChanged:(id)sender {
UITextField *text = (UITextField*)sender;
[nextButton setEnabled:(text.text.length != 0)];
}
É fácil no rápido.
override func shouldPerformSegueWithIdentifier(identifier: String,sender: AnyObject?) -> Bool {
return true
}
Como Abraham disse, verifique válido ou não na seguinte função.
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender
{
// Check this identifier is OK or NOT.
}
E, o performSegueWithIdentifier:sender:
chamado pela programação pode ser bloqueado substituindo o método a seguir. Por padrão, não está verificando se é válido ou não -shouldPerformSegueWithIdentifier:sender:
, podemos fazê-lo manualmente.
- (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];
}
[super performSegueWithIdentifier:identifier sender:sender];
realmente verdadeira?
performSegueWithIdentifier:sender:
método, e não chamá-lo de super
método.
Deve executar o segmento para o registro de logon
-(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);
}
Semelhante à resposta de Kaolin é deixar o seque conectado ao controle, mas validar o controle com base nas condições da exibição. Se você estiver acionando a interação da célula da tabela, também precisará definir a propriedade userInteractionEnabled, além de desativar o material na célula.
Por exemplo, eu tenho um formulário em uma exibição de tabela agrupada. Uma das células leva a outro tableView que atua como um selecionador. Sempre que um controle é alterado na exibição principal, eu chamo esse método
-(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;
}
}
Resposta rápida 4:
A seguir está a implementação do Swift 4 para cancelar 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
}
A outra maneira é substituir o método de tableView por willSelectRowAt e retornar nil se você não quiser mostrar o segue.
showDetails()
- é algum bool. Na maioria dos casos, deve ser implementado no modelo de dados representado na célula com indexPath
.
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}