Відповіді:
Це можливо в iOS 6 і пізніших версіях. Ви повинні реалізувати метод
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
На ваш погляд контролер. Ви робите там перевірку, і якщо це нормально, тоді, return YES;
якщо її немає, тоді return NO;
і підготовкаForSegue не викликається.
Зауважте, що цей метод не викликається автоматично при запуску програмних програм. Якщо вам потрібно здійснити перевірку, вам доведеться зателефонувати в callPerformSegueWithIdentifier, щоб визначити, чи слід виконувати segue.
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
Примітка: прийнята відповідь є найкращим підходом, якщо ви можете націлити на iOS 6. Для націлювання на iOS 5 ця відповідь буде дійсною.
Я не вірю, що можна скасувати сегмент в prepareForSegue
. Я б запропонував перенести вашу логіку до того, що performSegue
повідомлення вперше буде надіслане.
Якщо ви використовуєте програму Interface Builder для підключення каналу безпосередньо до елемента керування (наприклад, зв’язування каналу безпосередньо з a UIButton
), ви можете досягти цього за допомогою трохи рефакторингу. Підключіть segue до контролера перегляду замість конкретного елемента управління (видаліть старе посилання, а потім перетягніть його з самого контролера подання на контролер подання призначення). Потім створіть IBAction
у вашому контролері подання та підключіть елемент керування до IBAction. Тоді ви можете виконати свою логіку (перевірити наявність порожнього TextField) у створеному вами IBAction і вирішити, чи потрібно це performSegueWithIdentifier
програмно.
Swift 3 : func shouldPerformSegue (з ідентифікатором ідентифікатора: String, відправник: Будь-який?) -> Bool
Повернене значення відповідає дійсності, якщо слід проводити Segue або помилково, якщо його слід ігнорувати.
Приклад :
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
}
Крім того, дещо погана поведінка - запропонувати кнопку, яку користувач не повинен натискати. Ви можете залишити провідний канал як підставки, але почніть з відключеної кнопки. Потім підключіть "editingChanged" UITextField до події на алі управління перегляду
- (IBAction)nameChanged:(id)sender {
UITextField *text = (UITextField*)sender;
[nextButton setEnabled:(text.text.length != 0)];
}
Це легко в швидкому режимі.
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];
}
[super performSegueWithIdentifier:identifier sender:sender];
справді правдива?
performSegueWithIdentifier:sender:
метод, а не називаєте його, це super
метод.
Потрібно виконати 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);
}
Аналогічна відповідь Каоліна полягає в тому, щоб залишити послідовність, пов'язану з контролем, але перевірити контроль за умовами, які є в огляді. Якщо ви запускаєте взаємодію стільникової таблиці, вам також потрібно встановити властивість 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;
}
}
Відповідь 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
}
Інший спосіб - замінити метод tableView методом willSelectRowAt і повернути нуль, якщо ви не хочете показувати segue.
showDetails()
- це якийсь бул. У більшості випадків слід реалізувати в моделі даних, яка представлена в комірці з indexPath
.
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}