Ошибка при добавлении представления ввода в текстовое поле iOS 8

У меня возникла проблема, когда я добавляю пользовательское представление ввода в свое приложение на iOS 8. Это отлично работало на iOS 7, но при переключении на iOS 8 все терпит неудачу.

Это трассировка стека:

2014-06-03 21:23:54.237 MyApp[1910:47245] *** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<UICompatibilityInputViewController: 0x1103f9d40>
should have parent view controller:<StopChooser: 0x11083e200> but requested parent is:<UIInputWindowController: 0x110858800>'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001042eee35 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000103b919a0 objc_exception_throw + 45
    2   CoreFoundation                      0x00000001042eed6d +[NSException raise:format:] + 205
    3   UIKit                               0x00000001023d94cd -[UIViewController _addChildViewController:performHierarchyCheck:notifyWillMove:] + 184
    4   UIKit                               0x0000000102977a2b -[UIInputWindowController changeToInputViewSet:] + 416
    5   UIKit                               0x0000000102973f56 -[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:] + 185
    6   UIKit                               0x000000010297826a -[UIInputWindowController setInputViewSet:] + 526
    7   UIKit                               0x0000000102973c97 -[UIInputWindowController performOperations:withAnimationStyle:] + 50
    8   UIKit                               0x00000001027559bb -[UIPeripheralHost(UIKitInternal) setInputViews:animationStyle:] + 1054
    9   UIKit                               0x0000000102422afd -[UIResponder becomeFirstResponder] + 468
    10  UIKit                               0x00000001023235d3 -[UIView(Hierarchy) becomeFirstResponder] + 99
    11  UIKit                               0x00000001029cdbfb -[UITextField becomeFirstResponder] + 51
    12  UIKit                               0x0000000102655d61 -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] + 177
lib: terminating with uncaught exception of type NSException
    (lldb) 

Соответствующая часть - это несколько верхних строк. Кто-нибудь может это объяснить? Я звоню только myTextview.inputView = keyboard; Клавиатура представляет собой UIView, созданный в раскадровке и связанный через IBOutlet.


person Milo    schedule 04.06.2014    source источник


Ответы (12)


Я столкнулся с этой проблемой раньше.

Проблема:

  • Вы должны убедиться, что представление, которое вы назначите inputView или inputAccessoryView, не принадлежит ни одному родительскому представлению. Когда вы создаете эти представления из xib внутри ViewController, по умолчанию они устанавливаются как подпредставления суперпредставления.

Советы по решению:

  • Используйте метод removeFromSuperview для представления, которое вы назначите inputView или inputAccessoryView.
person Tuyen Nguyen    schedule 17.09.2014
comment
Для меня я добавлял их как подвид и устанавливал их как inputView/inputAccessoryView. Похоже, это хорошо работало в IOS7. В IOS8 я удалил addSubviews, чтобы исправить эту ошибку. - person Miro; 25.09.2014
comment
@ Миро, ты недостаточно ясно читаешь вопрос. Эта проблема возникает только на iOS8. До iOS8 все работает хорошо. - person Tuyen Nguyen; 26.09.2014
comment
Это не сработало для меня, но мой ответ ниже помог мне. - person Sasho; 30.09.2014
comment
В Swift и в методе viewDidLoad: добавьте self.myToolbar.removeFromSuperview() - person jonprasetyo; 25.06.2015
comment
у меня есть приложение для обмена сообщениями, у меня есть inputView (включая textField и Button), моя проблема заключается в том, что я добавляю его в подзаголовок и нажимаю на свою ячейку, чтобы показать UIMenueController (в методе beFirstResponder) (я получаю этот сбой) почему? - person Mo Farhand; 29.07.2015
comment
хорошо известно, что наличие inputAccessoryView с другим родителем работает на 13.4.1, но вылетает на 12.4 - person Kamen Dobrev; 04.09.2020

Непосредственно перед becomeFirstResponder удалите представление, которое вы используете для ввода, из суперпредставления:

mTextField.inputView = mInputVeiw;
[mInputVeiw removeFromSuperview];
[mTextField becomeFirstResponder];

Надеюсь, поможет.

person Rudi    schedule 22.09.2014

Вы должны убедиться, что представление, которое вы назначите inputView или inputAccessoryView, не принадлежит ни одному родительскому представлению.

Эта ошибка особенно раздражает, так как любое «входное представление», созданное в раскадровке (и, таким образом, добавленное к view VC), не может быть установлено как inputView или inputAccessoryView, не вызывая этого сбоя.

Если представление ввода не добавлено в view VC, представление ввода не будет доступно для визуального редактирования в раскадровке Interface Builder. Это видно только на левой панели раскадровки.

Как подключить панель инструментов Xcode Storyboard Simulated Metrics на реальную панель UIToolbar IBOutlet?

Я бы предпочел установить IB-соединение с inputAccessoryView непосредственно в раскадровке. Это вызывает этот сбой. Решение, которое я нашел, состоит в том, чтобы сделать вторичный IBOutlet подключенным к представлению в раскадровке, затем в viewDidLoad удалить его из суперпредставления, а затем сразу же назначить inputAccessoryView. Не уверен, что в конечном итоге я буду использовать это.

- (void)viewDidLoad {

    // ...

    [self.keybordView removeFromSuperview];
    self.inputAccessoryView = self.keybordView;
}
person pkamb    schedule 28.05.2015
comment
Большое спасибо за это! Вы должны убедиться, что представление, которое вы назначите для inputView или inputAccessoryView, не принадлежит ни одному родительскому представлению. это то, что, наконец, решило проблему, с которой я боролся. - person JohnV; 20.07.2018
comment
inputAccessoryView — это свойство getOnly. - person Prcela; 26.02.2019

Я понял. Я не уверен, в чем проблема была раньше, но вместо того, чтобы связать UIView в построителе интерфейса, я вместо этого создал UIView программно, и он работал нормально.

person Milo    schedule 11.06.2014
comment
Не могли бы вы уточнить это? Есть UITextField с inputView, установленным как UIPickerView. Где UIView вступает в игру? - person Clifton Labrum; 17.09.2014
comment
@CliftonLabrum нет UIPickerView - person Milo; 17.09.2014
comment
@CliftonLabrum Сделайте это программно: 1. создайте средство выбора 2. создайте пустой UITextField 3. установите UITextField.inputView = picker 4. добавьте [self.viewcontroller addSubview: myUITextField] - person jungledev; 05.09.2017

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

@property (weak, nonatomic) IBOutlet CustomView *inputAccessoryView;

Ошибка:

Terminating app due to uncaught exception
'UIViewControllerHierarchyInconsistency', reason: 'child view
controller:<UICompatibilityInputViewController: 0x7fed7063a1a0> should
have parent view controller:<MyViewController: 0x7fed70606f00> but
requested parent is:<UIInputWindowController: 0x7fed710cde00>'

Решение:

Проверьте наименование; не переопределять, если в этом нет необходимости.

person Octav    schedule 11.06.2017

У меня была такая же проблема, когда я пытался настроить свой UIDatePicker в своем UITextField.

- (void)setupViews {
    ...
    dobField.inputView = aDatePicker; // Here was the problem
    ...
}

Мое решение, я просто "выделяю" и "инициирую" свой datePicker в ViewDidLoad

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    ...
    aDatePicker = [[UIDatePicker alloc] init]; // My solution
    ...
}
person J. Lopes    schedule 30.09.2014

Я нашел решение, создающее UIView программно (например, предложенное Майло), но оно дает сбой, когда используется как @property. В моем случае мне нужно было создать экземпляр UIPickerView в viewDidLoad и привязать его к UITextView inputView. Когда мне нужно получить доступ к pickerView, я получаю это так

UIPickerView *picker = (UIPickerView *)self.myTextField.inputView;
person Lucio Fonseca    schedule 05.09.2014

Да, решение Tuyen Nguyen у меня не сработало. То, что сработало для меня в iOS 8/Xcode 6 для установки inputAccessoryView, было не removeFromSuperview, а вместо этого:

[[UIApplication sharedApplication].keyWindow addSubview:**MyViewToBeTheUIAccessoryView**];

Я надеюсь, что это поможет кому-то.

person Sasho    schedule 30.09.2014

Вызов removeFromSuperView в viewDidLoad не работает должным образом в модальных окнах. В итоге я скрыл представление, а затем удалил его из superView в viewDidAppear.

person aryaxt    schedule 08.03.2015

Большинство ответов, которые я получил, были связаны с изменениями кода. Я узнал, что удаление выхода в UIView внутри основного представления исправило это. https://stackoverflow.com/a/40037236/464313

person Adam Mendoza    schedule 14.10.2016

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

person slobodans    schedule 17.11.2016

У меня была такая же ошибка, когда я возвращаю любое представление из раскадровки как inputAccessoryView. Я исправил это с помощью childViewController. См. мой ответ здесь.

person ChikabuZ    schedule 27.05.2017