Antworten:
In iOS 6 und höher ist dies möglich: Sie müssen die Methode implementieren
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
In Ihrem View Controller. Dort führen Sie Ihre Validierung durch. Wenn dies in Ordnung ist, wird das prepareForSegue nicht aufgerufen, return YES;
wenn dies nicht return NO;
der Fall ist.
Beachten Sie, dass diese Methode beim programmgesteuerten Auslösen von Segues nicht automatisch aufgerufen wird. Wenn Sie die Prüfung durchführen müssen, müssen Sie shouldPerformSegueWithIdentifier aufrufen, um zu bestimmen, ob eine Übergabe durchgeführt werden soll.
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
Hinweis: Die akzeptierte Antwort ist der beste Ansatz, wenn Sie auf iOS 6 abzielen können. Für die Ausrichtung auf iOS 5 reicht diese Antwort aus.
Ich glaube nicht, dass es möglich ist, einen Übergang abzusagen prepareForSegue
. Ich würde vorschlagen, Ihre Logik an den Punkt zu verschieben, an dem die performSegue
Nachricht zum ersten Mal gesendet wird.
Wenn Sie Interface Builder verwenden, um einen Segue direkt mit einem Steuerelement zu verbinden (z. B. einen Segue direkt mit einem zu verknüpfen UIButton
), können Sie dies mit ein wenig Refactoring erreichen. Verbinden Sie den Segue mit dem Ansichts-Controller anstelle eines bestimmten Steuerelements (löschen Sie den alten Segue-Link und ziehen Sie ihn mit gedrückter Ctrl-Taste vom View-Controller selbst zum Ziel-View-Controller). Erstellen Sie dann einen IBAction
in Ihrer Ansicht befindlichen Controller und verbinden Sie das Steuerelement mit der IBAction. Anschließend können Sie in der soeben erstellten IBAction Ihre Logik ausführen (auf leeres TextField prüfen) und dort entscheiden, ob Sie performSegueWithIdentifier
programmgesteuert arbeiten möchten oder nicht .
Swift 3 : func shouldPerformSegue (withIdentifier-ID: String, Absender: Beliebig?) -> Bool
Rückgabewert true, wenn die Übergabe durchgeführt werden soll, oder false, wenn sie ignoriert werden soll.
Beispiel :
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
}
Alternativ ist es etwas schlecht, eine Schaltfläche anzubieten, die ein Benutzer nicht drücken sollte. Sie können den Segue als Ständer verkabelt lassen, aber mit deaktivierter Taste beginnen. Verbinden Sie dann das "editingChanged" des UITextField mit einem Ereignis im Ansichtssteuerelement
- (IBAction)nameChanged:(id)sender {
UITextField *text = (UITextField*)sender;
[nextButton setEnabled:(text.text.length != 0)];
}
Es ist einfach im Handumdrehen.
override func shouldPerformSegueWithIdentifier(identifier: String,sender: AnyObject?) -> Bool {
return true
}
Wie Abraham sagte, überprüfen Sie die Gültigkeit oder Nicht-Gültigkeit in der folgenden Funktion.
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender
{
// Check this identifier is OK or NOT.
}
Und das performSegueWithIdentifier:sender:
durch Programmieren aufgerufene kann durch Überschreiben der folgenden Methode blockiert werden. Standardmäßig wird nicht überprüft, ob gültig oder nicht gültig -shouldPerformSegueWithIdentifier:sender:
ist. Wir können dies manuell tun.
- (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];
wirklich wahr?
performSegueWithIdentifier:sender:
Methode überschreiben und nicht aufrufen super
.
Sollte Segue for Login Register durchführen
-(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);
}
Ähnlich wie bei Kaolin besteht die Antwort darin, die Sequenz mit der Kontrolle verbunden zu lassen, die Kontrolle jedoch anhand der Bedingungen in der Ansicht zu validieren. Wenn Sie auf die Interaktion mit Tabellenzellen zugreifen, müssen Sie auch die Eigenschaft userInteractionEnabled festlegen und die Inhalte in der Zelle deaktivieren.
Zum Beispiel habe ich ein Formular in einer gruppierten Tabellenansicht. Eine der Zellen führt zu einer anderen tableView, die als Auswahl fungiert. Immer wenn ein Steuerelement in der Hauptansicht geändert wird, rufe ich diese Methode auf
-(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;
}
}
Swift 4 Antwort:
Es folgt die Implementierung von Swift 4, um den Übergang abzubrechen:
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
}
Die andere Möglichkeit besteht darin, die Methode von tableView mit willSelectRowAt zu überschreiben und nil zurückzugeben, wenn Sie den Übergang nicht anzeigen möchten.
showDetails()
- Ist ein Idiot. In den meisten Fällen sollte in Datenmodell implementiert werden, das in Zelle mit dargestellt wird indexPath
.
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}