Клавиатура iPad не будет отклоняться, если модальный стиль представления ViewController - UIModalPresentationFormSheet - PullRequest
214 голосов
/ 30 июля 2010

Примечание:

См. Принятый ответ (не получивший наибольшее количество голосов) для решения с iOS 4.3.

Этот вопрос касаетсяповедение, обнаруженное в клавиатуре iPad, при которой он отказывается игнорироваться, если отображается в модальном диалоговом окне с контроллером навигации.

В основном, если я представляю навигационный контроллер со следующей строкой, как показано ниже:

navigationController.modalPresentationStyle = UIModalPresentationFormSheet;

Клавиатура отказывается отклоняться.Если я закомментирую эту строку, клавиатура исчезнет нормально.

...

У меня есть два текстовых поля, имя пользователя и пароль;имя пользователя имеет кнопку «Далее», а пароль - кнопку «Готово».Клавиатура не исчезнет, ​​если я представлю это в модальном навигационном контроллере.

РАБОТАЕТ

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' как контроллер модального вида, он работает.Проблема с навигационным контроллером?

РАБОТАЕТ

broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
b.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:b animated:YES];
[b release];

РАБОТАЕТ

broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
UINavigationController *navigationController = 
    [[UINavigationController alloc]
         initWithRootViewController:b];
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[b release];

Ответы [ 13 ]

172 голосов
/ 02 августа 2010

Это было классифицировано инженерами Apple как «работы по назначению».Я подал ошибку для этого некоторое время назад.Они рассуждают так: пользователь часто вводит данные в модальной форме, поэтому он пытается быть «полезным» и держать клавиатуру видимой, где обычно различные переходы в модальном представлении могут вызывать многократное отображение / скрытие клавиатуры.

edit: вот ответ инженера Apple на форумах разработчиков:

Был ли ваш взгляд случайно представлен в стиле UIModalPresentationFormSheet?Чтобы избежать частой анимации ввода-вывода, клавиатура иногда остается на экране, даже если нет первого респондента.Это не ошибка.

Это создает проблемы для многих людей (включая меня), но в настоящее время, похоже, нет способа обойти это.

ОБНОВЛЕНИЕ:

В iOS 4.3 и более поздних версиях теперь вы можете реализовать `-disablesAutomaticKeyboardDismissal 'на вашем контроллере представления, чтобы вернуть NO:

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

Это решает проблему.

149 голосов
/ 10 мая 2011

Будьте осторожны, если вы отображаете модальное с 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.

115 голосов
/ 31 марта 2011

В контроллере представления, который представлен модально, просто переопределите disablesAutomaticKeyboardDismissal, чтобы вернуть NO:

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}
51 голосов
/ 16 декабря 2010

Я решил это, используя стиль презентации 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];
1 голос
/ 24 мая 2014

Поместите этот код в ваше представлениеWillDisappear: метод текущего контроллера является еще одним способом исправить это:

Class UIKeyboardImpl = NSClassFromString(@"UIKeyboardImpl");
id activeInstance = [UIKeyboardImpl performSelector:@selector(activeInstance)];
[activeInstance performSelector:@selector(dismissKeyboard)];
1 голос
/ 09 мая 2012

Для тех, у кого проблемы с UINavigationController, смотрите мой ответ на похожий вопрос здесь: https://stackoverflow.com/a/10507689/321785

Edit: Я считаю это улучшением решения Михаа Хрибара (поскольку решение принимается там, где оно должно быть), а не комментарием Паскаля относительно категории на UIViewController

1 голос
/ 07 марта 2012

Вы также можете обойти это в универсальном приложении, просто проверив идиому и, если это iPad, вообще не поднимайте клавиатуру и позволяйте пользователю нажимать на то, что он хочет редактировать.* Возможно, это не самое удачное решение, но оно очень простое и не требует каких-либо хитроумных хаков, которые сломаются со следующим крупным выпуском iOS:)

1 голос
/ 09 декабря 2010

Если вы переключите другой модальный дисплей, вы можете заставить клавиатуру исчезнуть. Это не красиво и не оживляет, но вы можете заставить его уйти.

Было бы замечательно, если бы было исправление, но пока это работает. Вы можете вставить его в категорию на 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

0 голосов
/ 01 февраля 2018
Swift 4.1:
extension UINavigationController {
   override open var disablesAutomaticKeyboardDismissal: Bool {
      return false
   }
}
0 голосов
/ 22 июня 2015

Я обнаружил, что disablesAutomaticKeyboardDismissal и добавление функции disablesAutomaticKeyboardDismissal не работает для моего UITextField в модальном диалоге.

Экранная клавиатура просто не исчезнет.

Мое решение состояло в том, чтобы отключить все элементы управления вводом текста в моем диалоговом окне, а затем повторно включить соответствующие элементы через доли секунды.

Кажется, что, когда iOS видит, что ни один из UITextField элементов управления не включен, тогда избавляется от клавиатуры.

...