Ответ 1
В контроллере представления, который представлен модально, просто переопределите disablesAutomaticKeyboardDismissal
для возврата NO
:
- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}
Примечание:
См. принятый ответ (не самый высокий голос) для решения с iOS 4.3.
Этот вопрос относится к поведению, обнаруженному на клавиатуре iPad, где он отказывается отклоняться, если он показан в модальном диалоге с навигационным контроллером.
В принципе, если я представляю контроллер навигации следующей строкой, как показано ниже:
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
Клавиатура отказывается от увольнения. Если я прокомментирую эту строку, клавиатура уйдет отлично.
...
У меня есть два текстовых поля, имя пользователя и пароль; У пользователя есть кнопка "Далее", а пароль имеет кнопку "Готово". Клавиатура не исчезнет, если я покажу ее в модульном навигационном контроллере.
WORKS
broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
[self.view addSubview:b.view];
НЕ РАБОТАЕТ
broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
UINavigationController *navigationController =
[[UINavigationController alloc]
initWithRootViewController:b];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[b release];
Если я удалю часть контроллера навигации и представим "b" как контроллер модального представления, он будет работать. Проблема с навигационным контроллером?
WORKS
broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
b.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:b animated:YES];
[b release];
WORKS
broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
UINavigationController *navigationController =
[[UINavigationController alloc]
initWithRootViewController:b];
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[b release];
В контроллере представления, который представлен модально, просто переопределите disablesAutomaticKeyboardDismissal
для возврата NO
:
- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}
Это подразделение Apple разработало как "работает по назначению". Некоторое время назад я подал ошибку. Их аргументация заключается в том, что пользователь часто вводит данные в модальную форму, поэтому они пытаются быть "полезными" и держать клавиатуру видимой, где обычно различные переходы в модальном представлении могут вызвать повторное отображение/скрытие клавиатуры.
edit: вот ответ инженера Apple на форумах разработчиков:
Было ли ваше мнение каким-либо образом представлено стилем UIModalPresentationFormSheet? Чтобы избежать частых анимаций "взад-вперед", клавиатура иногда остается на экране, даже когда нет первого ответчика. Это не ошибка.
Это дает много проблем людям (включая меня), но на данный момент, похоже, нет способа обойти это.
UPDATE:
В iOS 4.3 и более поздних версиях теперь вы можете реализовать `-disablesAutomaticKeyboardDismissal 'на вашем контроллере представления, чтобы вернуть NO:
- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}
Это устраняет проблему.
Будьте осторожны, если вы показываете модальный код с помощью UINavigationController
. Затем вам нужно установить disablesAutomaticKeyboardDismissal
на контроллер навигации, а не на контроллер вида. Вы можете легко сделать это с помощью категорий.
Файл: UINavigationController + KeyboardDismiss.h
#import <Foundation/Foundation.h>
@interface UINavigationController (KeyboardDismiss)
- (BOOL)disablesAutomaticKeyboardDismissal;
@end
Файл: UINavigationController + KeyboardDismiss.m
#import "UINavigationController+KeyboardDismiss.h"
@implementation UINavigationController(KeyboardDismiss)
- (BOOL)disablesAutomaticKeyboardDismissal
{
return NO;
}
@end
Не забудьте импортировать категорию в файл, в котором вы используете UINavigationController.
Я решил это, используя стиль презентации UIModalPresentationPageSheet
и изменив его размер сразу после его представления. Например:
viewController.modalPresentationStyle = UIModalPresentationPageSheet;
viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:viewController animated:YES];
viewController.view.superview.autoresizingMask =
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin;
viewController.view.superview.frame = CGRectMake(
viewController.view.superview.frame.origin.x,
viewController.view.superview.frame.origin.y,
540.0f,
529.0f
);
viewController.view.superview.center = self.view.center;
[viewController release];
Если вы переключаете другой модальный дисплей, вы можете заставить клавиатуру исчезнуть. Это не очень красиво, и оно не анимируется, но вы можете заставить его уйти.
Было бы здорово, если бы было исправление, но пока это работает. Вы можете клинировать его в категории на UIViewController
и называть его, когда вы хотите, чтобы клавиатура ушла:
@interface _TempUIVC : UIViewController
@end
@implementation _TempUIVC
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
@end
@implementation UIViewController (Helpers)
- (void)_dismissModalViewController {
[self dismissModalViewControllerAnimated:NO];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
[self release];
}
- (void)forceKeyboardDismissUsingModalToggle:(BOOL)animated {
[self retain];
_TempUIVC *tuivc = [[_TempUIVC alloc] init];
tuivc.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:tuivc animated:animated];
if (animated) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_dismissModalViewController) name:UIKeyboardDidHideNotification object:nil];
} else
[self _dismissModalViewController];
[tuivc release];
}
@end
Будьте осторожны с этим, когда вы просматриваетеDidAppear/viewDidDisappear и вызываете все эти методы. Как я уже сказал, это не очень, но работает.
-Adam
Вы также можете обойти это в универсальном приложении, просто проверив идиому, и если это iPad, вообще не всплывайте клавиатуру и не позволяйте пользователю нажимать все, что они хотят редактировать.
Может быть, не самое приятное решение, но оно очень простое и не нуждается в каких-либо причудливых хаках, которые сломаются со следующей крупной версией iOS:)
Для тех, у кого проблемы с UINavigationController, см. мой ответ на аналогичный вопрос: fooobar.com/questions/30945/...
Изменить: Я считаю это усовершенствованием решения Михи Хрибара (поскольку решение происходит там, где оно должно), и в отличие от комментария Паскаля относительно категории на UIViewController
Поместите этот код в свой viewWillDisappear: метод текущего контроллера - это еще один способ исправить это:
Class UIKeyboardImpl = NSClassFromString(@"UIKeyboardImpl");
id activeInstance = [UIKeyboardImpl performSelector:@selector(activeInstance)];
[activeInstance performSelector:@selector(dismissKeyboard)];
возможно, не вернет НЕТ, но ДА. Так что это может исчезнуть.
И у вас есть textFieldShouldEndEditing
, возвращающий YES?
И почему вы стреляете жаль, что я вижу сейчас[nextResponder becomeFirstResponder]
?!
У меня также есть несколько UITextViews которые все имеют свои "редактируемые" свойство установлено в FALSE.
Можно ли предположить, что ни одно из них не имеет значения tag
secondField.tag+1
? Если это так, вы говорите им, чтобы они стали первым ответчиком, вместо того, чтобы уволить первого ответчика. Может быть, поместить некоторые NSLog() в структуру if.
Я уверен, что вы посмотрели на это, но вы уверены, что ваш класс контроллера правильно подключен как делегат UITextField, правильно?
может быть не идеальным решением, но работает
[self.view endEditing: YES],
где бы ни была ваша кнопка или жест, чтобы представить модальные
Я обнаружил, что disablesAutomaticKeyboardDismissal
и добавление функции disablesAutomaticKeyboardDismissal
не работает для моего UITextField
в модальном диалоговом окне.
Экранная клавиатура просто не исчезнет.
Мое решение состояло в том, чтобы отключить все элементы ввода текста в моем диалоговом окне, а затем снова включить соответствующие части через секунду.
Кажется, что когда iOS видит, что ни один из элементов управления UITextField
не включен, тогда он избавляется от клавиатуры.
Swift 4.1:
extension UINavigationController {
override open var disablesAutomaticKeyboardDismissal: Bool {
return false
}
}