【问题标题】:How to hide inputAccessoryView without dismissing keyboard如何在不关闭键盘的情况下隐藏 inputAccessoryView
【发布时间】:2026-01-09 16:20:06
【问题描述】:

我在 textView 的 inputAccessoryView 属性中使用工具栏。当键盘显示时,它会按预期显示工具栏。当设备旋转时,我想删除工具栏。我试过了:

 myTextView.inputAccessoryView.hidden = !layoutIsPortrait;

这确实隐藏了工具栏,但留下了较高键盘的轮廓。键盘的大小显然仍然适合工具栏。它看起来很糟糕,并且会干扰底层响应者的触摸事件。

 myTextView.inputAccessoryView = nil;

只有在我辞职FirstResponder,然后再次成为FirstResponder 时才有效。这是不可接受的。我失去了 textView 的光标位置和内容,键盘一闪一闪。

[myTextView.inputAccessoryView removefromSuperview];

什么都不做。 我在 iVar 中保存了对工具栏的引用并解决了这个问题,

[myIvarReference removeFromSuperview];

这行得通,但键盘的较高轮廓再次隐约可见。这一次它不干涉其他观点的接触。所以现在这是一个可行的解决方案,但在视觉上是不可接受的。 我还能尝试随意显示和隐藏 inputAccessoryView 吗?

屏幕截图 - 键盘上方的微弱线条是已移除工具栏的残余

【问题讨论】:

  • 您介意张贴您所说的“较高键盘的轮廓”的屏幕截图吗?我觉得您提到的解决方案应该有效(至少其中一个),但我不确定您在美学上可以接受什么...
  • 我添加了截图的特写
  • 我现在无法测试它,但 myTextView.inputAccessoryView.frame = CGRectZero 是否符合您的要求?
  • 我现在也不能尝试。我希望这与 removeFromSuperView 的结果相同。我的猜测是,需要调整大小的是包含键盘和工具栏的视图。如果不进入一些私有 api 领域,我不知道如何导致这种情况发生。

标签: iphone ios uitoolbar uikeyboard


【解决方案1】:

从未找到改变键盘框架的方法。最终决定放弃 inputAccessoryView,将我的工具栏作为子视图直接添加到视图中,并直接与键盘一起为其设置动画。这使两者保持独立,因此,没有更多的线。

【讨论】:

    【解决方案2】:
    myTextView.inputAccessoryView = nil;
    [myTextView reloadInputViews];
    

    这会从视图中删除工具栏并重新加载视图。这样你就不需要调用 resignFirstResponder 和 becomeFirstResponder。此外,这仍将保留您的光标位置和内容。

    【讨论】:

    • 谢谢。我在找这个。这应该是公认的答案。 1 起来!
    • 谢谢。我使用 relaodInputViews 使工具栏中的更改变得可见,而无需通过辞职/成为 FirstResponder
    【解决方案3】:

    对我来说,Eric 的解决方案从未真正重置框架或触摸区域。大概这是苹果处理事情的一个错误。但是,我找到了一种解决方法,可以为我解决问题。当我设置一个没有框架的新 inputAccessoryView 时,reloadInputViews 工作正常:

    myTextView.inputAccessoryView = [[UIView alloc] initWithFrame: CGRectZero];
    [myTextView reloadInputViews];
    

    【讨论】:

      【解决方案4】:

      上面的答案都不适合我,并且 reloadInputViews 导致了奇怪的问题。最终,我通过以下方式让它显示和隐藏并通过:

      隐藏它:

      [textview.inputAccessoryView setHidden:YES];
      [textview.inputAccessoryView setUserInteractionEnabled:NO];
      

      显示它:

      [textview.inputAccessoryView setHidden:NO];
      [textview.inputAccessoryView setUserInteractionEnabled:YES];
      

      【讨论】:

      • 这是最好的答案,它不会导致输入视图重新加载,也不会减慢输入速度
      【解决方案5】:

      Xamarin 代码是

      Control.InputAccessoryView = new UIView(CGRect.Empty);
      Control.ReloadInputViews();
      

      【讨论】:

      • 一般来说,一个答案应该不仅仅是一个代码sn-p,就像一些解释它为什么起作用的解释。
      • 这只是 jungziege 为 xamarin 重新编写的答案...................... ..
      • 然后将您的答案归为此类,例如“将 Jungziege 的答案转换为 C# 和 Xamarin 产量...”特别是在您的答案建立在其他人的答案之上的情况下,参考原始答案是有用且礼貌的也回答。
      【解决方案6】:

      根据 Eric Appel 的回答:

      myTextView.inputAccessoryView = nil;
      [myTextView reloadInputViews];
      hideInputAccessoryView = YES;
      

      进一步修改:

      - (BOOL)canBecomeFirstResponder
      {
          BOOL showInputAccessoryView = YES;
      
          if (hideInputAccessoryView)
              showInputAccessoryView = NO;
      
          return showInputAccessoryView;
      }
      

      这应该隐藏 InputAccessoryView,即使在键盘退出时也是如此。

      【讨论】:

        【解决方案7】:

        奇怪的是,这些方法都不适用于我的情况。

        我有一个搜索控制器,如果选择了特定的搜索范围,它会弹出一个标准的 Apple iOS 键盘,如果选择了其他范围,我有一个带有集合视图作为输入字段的自定义键盘视图。 在这两种情况下,当显示输入视图时,屏幕上都会绘制一个不需要的附件视图。

        所以,

        self.mySearch.searchbar.inputAccessoryView = nil // did not work
        
        [self.mySearch.searhbar.inputAccessoryView setHidden:YES] // did not work
        
        self.mySearch.inputAccessoryView = nil  // did not work
        
        self.mySearch.searchbar.inputAccessoryView.frame = CGRectZero //did not work
        
        [self.mySearch reloadInputViews]
        

        及其各种组合等。

        起作用的是从附件视图中删除单个附件项目:

         // insert after assignments of mySearch delegates
        UITextInputAssistantItem *junk = [self.mySearch inputAssistantItem];
        junk.leadingBarButtonGroups = @[];
        junk.trailingBarButtonGroups = @[];
        

        【讨论】:

        • 无法按预期工作导致输入刷新并减慢文本输入速度
        【解决方案8】:
        mTextView.inputAccessoryView = [[UIView alloc] initWithFrame:CGRectZero];
        [mTextView reloadInputViews];
        

        对我有用,将 inputAccessoryView 设置为 nil 将不起作用,我只是不知道为什么。

        【讨论】:

        • 成功了。我试图添加两个工具栏。第一个是我添加默认值,第二个是在选择文本时尝试添加。当我使用relaodInputViews 时,它起作用了。
        【解决方案9】:

        Xcode 11.6 和 iOS 13.6

        当键盘出现时,我试图添加两个工具栏。

        首先,我添加了viewDidLoad

        self.textView.inputAccessoryView = self.addDefaultToolbar()

        当键盘出现时,我在 UItextView 中选择了text 并尝试添加第二个工具栏选项

        这里的代码在text 的选择中没有显示Toolbar

        func textViewDidChangeSelection(_ textView: UITextView) {
            if let selectedRange = textView.selectedTextRange{
                let selectedText = textView.text(in: selectedRange)
                if selectedText != nil && selectedText!.count > 0{
                    print("selectedText - \(selectedText!)")
                    
                    if self.defaultToolBar != nil{
                        self.defaultToolBar?.removeFromSuperview()
                        self.defaultToolBar = nil
                    }
                    
                    self.textView.inputAccessoryView = self.addSelectionToolbar()
                }
                else{
                    print("not selectedText - \(selectedText!)")
                    
                    if self.selectionToolBar != nil{
                        self.selectionToolBar?.removeFromSuperview()
                        self.selectionToolBar = nil
                    }
                    
                    
                    self.textView.inputAccessoryView = self.addDefaultToolbar()
                    
                }
            }
        }
        

        添加self.textView.reloadInputViews() 后,我可以看到第二个工具栏发生变化,反之亦然。

        工作代码。

        func textViewDidChangeSelection(_ textView: UITextView) {
            if let selectedRange = textView.selectedTextRange{
                let selectedText = textView.text(in: selectedRange)
                if selectedText != nil && selectedText!.count > 0{
                    print("selectedText - \(selectedText!)")
                    
                    if self.defaultToolBar != nil{
                        self.defaultToolBar?.removeFromSuperview()
                        self.defaultToolBar = nil
                    }
                    
                    self.textView.inputAccessoryView = self.addSelectionToolbar()
                    self.textView.reloadInputViews()
                }
                else{
                    print("not selectedText - \(selectedText!)")
                    
                    if self.selectionToolBar != nil{
                        self.selectionToolBar?.removeFromSuperview()
                        self.selectionToolBar = nil
                    }
                    
                    
                    self.textView.inputAccessoryView = self.addDefaultToolbar()
                    self.textView.reloadInputViews()
                    
                }
            }
        }
        

        【讨论】:

          【解决方案10】:

          斯威夫特 5

          我用这个:

          view.autocorrectionType = .no
          

          【讨论】:

            最近更新 更多