Odpowiedzi:
Jest to możliwe w iOS 6 i nowszych: Musisz zaimplementować tę metodę
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
W twoim kontrolerze widoku. Dokonujesz tam walidacji, a jeśli wszystko jest w porządku, to return YES;
jeśli nie, to nie return NO;
jest wywoływana funkcja PrepForSegue.
Zauważ, że ta metoda nie jest wywoływana automatycznie podczas programowego uruchamiania segu. Jeśli musisz wykonać sprawdzenie, musisz wywołać funkcję shouldPerformSegueWithIdentifier, aby ustalić, czy wykonać segue.
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
Uwaga: zaakceptowana odpowiedź jest najlepszym podejściem, jeśli możesz kierować reklamy na iOS 6. W przypadku targetowania na iOS 5 ta odpowiedź będzie wystarczająca.
Nie sądzę, że można anulować segue w prepareForSegue
. Sugerowałbym przeniesienie logiki do punktu, w którym performSegue
wiadomość jest wysyłana po raz pierwszy.
Jeśli używasz Konstruktora interfejsów, aby podłączyć segue bezpośrednio do kontrolki (np. Łącząc segue bezpośrednio z a UIButton
), możesz to zrobić przy odrobinie refaktoryzacji. Połącz segue z kontrolerem widoku zamiast określonego kontrolki (usuń stare łącze segue, a następnie przeciągnij z samego kontrolera widoku do docelowego kontrolera widoku). Następnie utwórz IBAction
kontroler widoku i połącz go z sekcją IBAction. Następnie możesz wykonać swoją logikę (sprawdzić, czy pole TextField jest puste) w utworzonym IBAction i zdecydować, czy performSegueWithIdentifier
programować.
Swift 3 : func shouldPerformSegue (withIdentifier identifier: String, sender: Any?) -> Bool
Zwraca wartość true, jeśli należy wykonać segment, lub false, jeśli należy go zignorować.
Przykład :
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
}
Alternatywnie, nieco złym zachowaniem jest oferowanie przycisku, którego użytkownik nie powinien naciskać. Możesz zostawić segue okablowanym jako stojaki, ale zacznij od wyłączonego przycisku. Następnie połącz „editChanged” UITextField ze zdarzeniem w ala kontroli widoku
- (IBAction)nameChanged:(id)sender {
UITextField *text = (UITextField*)sender;
[nextButton setEnabled:(text.text.length != 0)];
}
Łatwo jest szybko.
override func shouldPerformSegueWithIdentifier(identifier: String,sender: AnyObject?) -> Bool {
return true
}
Jak powiedział Abraham, sprawdź poprawność lub nie w następującej funkcji.
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender
{
// Check this identifier is OK or NOT.
}
I performSegueWithIdentifier:sender:
wywoływane przez programowanie można zablokować, zastępując następującą metodę. Domyślnie nie sprawdza poprawności lub nie -shouldPerformSegueWithIdentifier:sender:
, możemy to zrobić ręcznie.
- (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];
naprawdę prawdziwa?
performSegueWithIdentifier:sender:
metodę, a nie wywołasz jej, to super
metoda.
Powinieneś wykonać Segue dla logowania Zarejestruj się
-(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);
}
Podobnie do odpowiedzi Kaolina jest pozostawienie seque podłączonego do kontroli, ale sprawdzenie poprawności na podstawie warunków w widoku. Jeśli odpalasz interakcję komórki tabeli, musisz również ustawić właściwość userInteractionEnabled, a także wyłączyć rzeczy w komórce.
Na przykład mam formularz w zgrupowanym widoku tabeli. Jedna z komórek prowadzi do innego tableView, który działa jak próbnik. Za każdym razem, gdy kontrola jest zmieniana w głównym widoku, wywołuję tę metodę
-(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;
}
}
Odpowiedź Swift 4:
Poniżej przedstawiono implementację Swift 4, aby anulować 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
}
Innym sposobem jest zastąpienie metody tableView za pomocą willSelectRowAt i zwrócenie wartości zero, jeśli nie chcesz wyświetlać segue.
showDetails()
- jest trochę bool. W większości przypadków powinien być zaimplementowany w modelu danych reprezentowanym w komórce za pomocą indexPath
.
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}