Ответы:
Это возможно в iOS 6 и более поздних версиях: необходимо реализовать метод
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
На ваш взгляд контроллер. Вы делаете свою проверку там, и если все в порядке, то return YES;
если нет, то return NO;
и метод prepareForSegue не вызывается.
Обратите внимание, что этот метод не вызывается автоматически при программном запуске сегментов. Если вам нужно выполнить проверку, то вы должны вызвать shouldPerformSegueWithIdentifier, чтобы определить, следует ли выполнять переход.
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
Примечание: принятый ответ является наилучшим подходом, если вы можете настроить таргетинг на iOS 6. Для таргетинга на iOS 5 этот ответ подойдет.
Я не верю, что можно отменить переход prepareForSegue
. Я бы предложил перенести вашу логику так, чтобы performSegue
сообщение было отправлено первым.
Если вы используете Interface Builder для соединения перехода непосредственно с элементом управления (например, связывание перехода непосредственно с a UIButton
), то вы можете выполнить это с помощью небольшого рефакторинга. Подключите переход к контроллеру представления вместо определенного элемента управления (удалите старую ссылку перехода, а затем перетащите элемент управления из самого контроллера представления в целевой контроллер представления). Затем создайте IBAction
в своем контроллере представления и подключите элемент управления к IBAction. Затем вы можете выполнить свою логику (проверить наличие пустого TextField) в IBAction, который вы только что создали, и решить, делать это или нет performSegueWithIdentifier
программно.
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
}
С другой стороны, предлагать кнопку, которую пользователь не должен нажимать, несколько плохо. Вы можете оставить переход подключенным как стенды, но начать с отключенной кнопки. Затем подключите UITextField «editChanged» к событию на панели управления представлением
- (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
метод.
Должен выполнить 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);
}
Аналогично ответу Каолина - оставить след, привязанный к элементу управления, но проверить элемент управления на основе условий в представлении. Если вы используете взаимодействие с ячейками таблицы, вам также необходимо установить свойство 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 и вернуть nil, если вы не хотите показывать результат.
showDetails()
- это какая-то глупость. В большинстве случаев должна быть реализована модель данных, представленная в ячейке с indexPath
.
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}