Question

I'm having an issue when I add a custom input view to my app on iOS 8. This was working perfectly fine on iOS 7 but when switching to iOS 8 everything fails.

This is the stack trace:

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) 

The relevant part being the top few lines. Can someone explain this? All I'm calling is myTextview.inputView = keyboard; Keyboard being a UIView created in the storyboard and linked via IBOutlet.

Was it helpful?

Solution

I encountered this problem before.

Problem:

  • You have to ensure that the view you will assign to inputView or inputAccessoryView doesn't belong to any parent view. When you create these views from a xib inside a ViewController, by default they are set as subviews of a superview.

Solution Tips:

  • Use the method removeFromSuperview on the view you will assign to inputView or inputAccessoryView

OTHER TIPS

Just before becomeFirstResponder remove the View you use for input from the superview :

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

Hope it helps.

You have to ensure that the view you will assign to inputView or inputAccessoryView don't belong to any parent view.

This error is especially annoying as any "input view" created in a storyboard (and thus added to the VC's view) cannot be set as the inputView or inputAccessoryView without causing this crash.

If the input view is not added to the VC's view, the input view will not be available for visual editing in the Interface Builder Storyboard. It's only visible in the Storyboard's left pane.

How to connect Xcode Storyboard's "Simulated Metrics" toolbar to an actual IBOutlet UIToolbar?

I'd prefer to make an IB Connection to the inputAccessoryView directly in the Storyboard. That causes this crash. A solution I found is to make a secondary IBOutlet connected to the view in the Storyboard, then in viewDidLoad remove it from the super view then immediately assign to inputAccessoryView. Not sure if I'll end up using this.

- (void)viewDidLoad {

    // ...

    [self.keybordView removeFromSuperview];
    self.inputAccessoryView = self.keybordView;
}

I figured it out. I'm not sure what the issue was before but instead of linking a UIView in interface builder, I instead created a UIView programmatically and it worked fine.

My problem was that I have named a view having a textField 'inputAccessoryView'...

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

Error:

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>'

Solution:

Check the naming; do not override if not needed.

I had the same problem when I tried to setup my UIDatePicker in my UITextField

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

My solution, I just "alloc" and "init" my datePicker in ViewDidLoad

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

I found the solution creating the UIView programmatically (Like suggested by Milo), but it crashes when its used like a @property. In my case, I needed to create the UIPickerView instance in viewDidLoad and assing to UITextView inputView. When I need to acess the pickerView I get it like this

UIPickerView *picker = (UIPickerView *)self.myTextField.inputView;

Yeah, the Tuyen Nguyen solution did not work for me. What worked for me in iOS 8 / Xcode 6 for setting an inputAccessoryView was not to removeFromSuperview but instead:

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

I hope this helps someone.

Calling removeFromSuperView in viewDidLoad doesn't seem to work properly in modals. I ended up setting the view hidden, and then removing it from superView in viewDidAppear.

Most answers I was were related to code changes. I found out that deleting an outlet to the UIView inside the main view fixed it. https://stackoverflow.com/a/40037236/464313

My solution for this problem was to add view to inputView, but not to add view controller to parent.

I had the same error when I return any view from storyboard as inputAccessoryView. I fixed it with childViewController. See my answer here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top