67

当我在 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; 键盘是在情节提要中创建并通过 IBOutlet 链接的 UIView。

4

12 回答 12

117

我以前遇到过这个问题。

问题

  • 您必须确保您将分配给inputViewinputAccessoryView不属于任何父视图的视图。当您从 ViewController 中的 xib 创建这些视图时,默认情况下它们被设置为超级视图的子视图。

解决方案提示

  • 使用removeFromSuperview您将分配给的视图上的方法inputViewinputAccessoryView
于 2014-09-17T04:23:10.217 回答
20

就在becomeFirstResponder从 superview 删除您用于输入的 View 之前:

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

希望能帮助到你。

于 2014-09-22T06:58:06.207 回答
3

您必须确保您将分配给inputViewinputAccessoryView不属于任何父视图的视图。

这个错误特别烦人,因为在情节提要中创建的任何“输入视图”(并因此添加到 VC 中view)都不能设置为inputViewinputAccessoryView不导致此崩溃。

如果输入视图未添加到 VC 中view,则输入视图将无法在 Interface Builder Storyboard 中进行可视化编辑。它仅在情节提要的左窗格中可见。

如何将 Xcode Storyboard 的“模拟指标”工具栏连接到实际的 IBOutlet UIToolbar?

我更喜欢inputAccessoryView直接在情节提要中建立 IB 连接。这导致了这次崩溃。我发现的一个解决方案是使辅助 IBOutlet 连接到情节提要中的视图,然后viewDidLoad将其从超级视图中删除,然后立即分配给inputAccessoryView. 不确定我是否会最终使用它。

- (void)viewDidLoad {

    // ...

    [self.keybordView removeFromSuperview];
    self.inputAccessoryView = self.keybordView;
}
于 2015-05-28T01:34:58.500 回答
2

我想到了。我不确定之前的问题是什么,但我没有链接UIView界面构建器,而是以UIView编程方式创建了一个,它工作正常。

于 2014-06-11T22:35:35.267 回答
2

我的问题是我已经命名了一个具有 textField '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>'

解决方案:

检查命名;如果不需要,不要覆盖。

于 2017-06-11T22:18:55.297 回答
1

我找到了以编程方式创建 UIView 的解决方案(就像 Milo 建议的那样),但是当它像 @property 一样使用时它会崩溃。在我的情况下,我需要在 viewDidLoad 中创建 UIPickerView 实例并分配给 UITextView inputView。当我需要访问pickerView时,我会这样

UIPickerView *picker = (UIPickerView *)self.myTextField.inputView;
于 2014-09-05T16:31:22.353 回答
1

是的,Tuyen Nguyen 解决方案对我不起作用。在 iOS 8 / Xcode 6 中设置 inputAccessoryView 对我有用的不是,removeFromSuperview而是:

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

我希望这可以帮助别人。

于 2014-09-30T13:00:43.983 回答
1

当我尝试在我的 UITextField 中设置我的 UIDatePicker 时,我遇到了同样的问题

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

我的解决方案,我只是在 ViewDidLoad 中“分配”和“初始化”我的 datePicker

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    ...
    aDatePicker = [[UIDatePicker alloc] init]; // My solution
    ...
}
于 2014-09-30T14:33:44.037 回答
0

removeFromSuperView在模态中调用viewDidLoad似乎无法正常工作。我最终将视图设置为隐藏,然后将其从 superView 中删除viewDidAppear

于 2015-03-08T17:30:05.540 回答
0

我得到的大多数答案都与代码更改有关。我发现删除主视图内的 UIView 的出口修复了它。https://stackoverflow.com/a/40037236/464313

于 2016-10-14T07:23:38.323 回答
0

我对这个问题的解决方案是将视图添加到 inputView,而不是将视图控制器添加到父级。

于 2016-11-17T12:43:58.847 回答
0

当我从情节提要返回任何视图时,我遇到了同样的错误inputAccessoryView。我用 childViewController 修复了它。在这里查看我的答案。

于 2017-05-27T16:44:32.643 回答