视图设置为 inputAccessoryView 在添加回普通视图时抛出异常

Posted

技术标签:

【中文标题】视图设置为 inputAccessoryView 在添加回普通视图时抛出异常【英文标题】:View set as inputAccessoryView throws exception when added back into normal view 【发布时间】:2015-06-10 20:33:42 【问题描述】:

我在一个视图中有一个文本视图、一些装饰等,我希望该视图停靠在键盘上,就像任何其他消息传递应用程序一样。

当我要显示我的文本视图时,下面是我将视图附加到键盘的方法:

-(BOOL)textViewShouldBeginEditing:(UITextView *)textView
    UIView *inputView = self.textInputView; //connected at IB outlet from storyboard, also contains the text view itself.
    constraintsOfTextInputView = [self constraintsRelatedToView:inputView]; //to be able to add them again
    [[UIApplication sharedApplication].keyWindow addSubview:self.textInputView];
    textView.inputAccessoryView = inputView;
    editingTextView = textView;
    return YES;

当解雇时:

//using notification hook for UIKeyboardWillHideNotification because
//textView[Will|Did]EndEditing is called too late

-(void)keyboardWillHide
    if(editingTextView && constraintsOfTextInputView)
        editingTextView.inputAccessoryView = nil;
        [self.textInputView removeFromSuperview];
        [self.view addSubview:self.textInputView]; <--- EXCEPTION
        [self.view addConstraints:constraintsOfTextInputView];
        [self.view layoutIfNeeded];

        editingTextView = nil;
        constraintsOfTextInputView = nil;
    

即使我的操作与添加时的操作完全相反,我还是遇到了这个异常:

*** Terminating app due to uncaught exception
'UIViewControllerHierarchyInconsistency', reason: 'child view controller:
<UICompatibilityInputViewController: 0x13307ba20> should have parent view
controller:<ULPostViewController: 0x1307a7c00> but actual parent is:
<UIInputWindowController: 0x12f0be200>'

我怎样才能摆脱这个问题?我使用的是 ios 8(不支持旧版本)。

更新:我创建了一个 git 存储库来演示问题:

https://github.com/can16358p/CPInputAccessoryTest

【问题讨论】:

inputAccessoryView 无法添加到任何其他视图。除了将其设置为 inputAccessoryView 之外,为什么还要将其作为子视图添加到窗口中? @rmaddy 因为如果我不这样做,它就不会显示。 @CanPoyrazoğlu UIKit 应该负责显示您的输入视图。 @ChristianSchnorr 但事实并非如此。如果我不将它添加到窗口中,它就会在编辑开始时消失。 @CanPoyrazoğlu 你能在某处上传一个示例项目吗?这是不可能的。 【参考方案1】:

您正在滥用inputView 来获取并非如此的东西。输入视图应该用于查看用户输入数据,输入附件视图是您可能想要扩展的东西。但它应该是键盘之类的东西。

您的文本视图不是其中的一部分。它是用户输入数据的视图。决定是否要将视图作为输入视图或在主视图层次结构中,但不要在两者之前移动它。

您真正的问题是您想在键盘出现时移动文本视图以使其可见。为此,请观察键盘通知

UIKeyboardWillShowNotification
UIKeyboardDidShowNotification
UIKeyboardWillHideNotification
UIKeyboardDidHideNotification

并相应地移动您的视图。例如,您可以调整视图控制器的视图边界原点,以向上移动所有内容。

【讨论】:

不,您的建议实际上是我试图避免的事情。我正在努力实现这里的目标:derpturkey.com/uitextfield-docked-like-ios-messenger 我无法让它工作。无论我尝试什么,我都无法摆脱这个错误。 //我所说的“它”是指我自己的项目基于那个。 它显然没有用,我又回到了这个次优的解决方案。但是,我使用键盘的框架更改而不是将/确实显示/隐藏。 由您决定收听哪些通知。我更喜欢显示/隐藏的,因为它们告诉我是否可以忽略框架键。 顺便说一句,我试图摆脱这种方法的原因是真正将自定义视图“停靠”在键盘顶部,就像 FB Messenger 一样。我不知道他们是怎么做到的,但是当通过垂直平移交互地解除键盘时,它感觉真正停靠并且仍然平滑地连接到键盘。使用框架方法,我得到了一个非常接近的近似值,但它仍然不完美。【参考方案2】:

您可以将文本视图用作整个视图控制器的输入附件视图。见my pull request。

除了不断增长的文本视图部分,这几乎是 Messages 应用程序的行为。

【讨论】:

我明白了。顺便说一句,我查看了您的拉取请求,我认为您已经删除了情节提要文件,但是当我尝试运行它时,它要求提供情节提要文件并崩溃。 很奇怪,它对我来说并没有崩溃。现在应该修好了。

以上是关于视图设置为 inputAccessoryView 在添加回普通视图时抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

没有为 UITextField 正确添加 inputAccessoryView

inputAccessoryView 没有在 iPhone X 上获得触摸事件

inputAccessoryView 未显示在键盘上方

在解除inputAccessoryView设置为toolbarItems的键盘后,toolbarItems消失

iPad 上带有 UITextView 的 InputAccessoryView

UITableView 作为 inputAccessoryView 的高度为零