it-swarm.com.ru

Клавиатура iPad не будет отклоняться, если модальный стиль представления ViewController - UIModalPresentationFormSheet

Примечание:

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

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

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

navigationController.modalPresentationStyle = UIModalPresentationFormSheet;

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

...

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

РАБОТАЕТ

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];
214
Kalle

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

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}
115
Sebastian H

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

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

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

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

UPDATE:

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

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

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

172
Mike Weller

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

149
Miha Hribar

Я решил это, используя стиль представления 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];
51
azdev

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

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

1
Chris Trahey

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

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

-Адам

1
Adam

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

Class UIKeyboardImpl = NSClassFromString(@"UIKeyboardImpl");
id activeInstance = [UIKeyboardImpl performSelector:@selector(activeInstance)];
[activeInstance performSelector:@selector(dismissKeyboard)];
1
Story

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

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

1
Maciej Swic

может быть не идеальное решение, но работает
[self.view endEditing: ДА];
от того, где ваша кнопка или жест реализован для представления модальных

0
Tanuj Jagoori

возможно не вернуть НЕТ, но ДА. Так что это может уйти.

И у вас есть textFieldShouldEndEditing, возвращающий YES?

И почему ты стреляешь [nextResponder becomeFirstResponder] ?! извини я вижу сейчас

У меня также есть несколько UITextViews, у каждого из которых свойство "editable" установлено в FALSE.

Можем ли мы предположить, что ни один из них, случайно, не имеет значения tagsecondField.tag+1? Если это так, вы говорите им стать первым респондентом, а не уходить в отставку первым. Возможно, поместите NSLog () в структуру if.

0
mvds

Я уверен, что вы смотрели на это, но вы уверены, что ваш класс контроллера правильно подключен как делегат UITextField, верно?

0
Neal L
Swift 4.1:
extension UINavigationController {
   override open var disablesAutomaticKeyboardDismissal: Bool {
      return false
   }
}
0
fivewood

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

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

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

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

0
Mike Gledhill