键盘解除后,将inputAccessoryView保持可见状态

时间:2012-05-26 18:14:40

标签: ios user-interface uitoolbar uikeyboard

我要做的是在iPad上的Safari中创建类似于“在页面上查找”搜索功能的内容。

我正在使用UIToolbar包含一些项目,并通过inputAccessoryView上的UITextField将其附加到键盘上。像魅力一样,但有一件事我无法弄清楚。在Safari中,当您搜索某些内容时,键盘会消失,但工具栏仍保留在屏幕底部。

有没有人知道如何做到这一点?我能想到的唯一解决方案是响应键盘被解除的事件,然后拉出UIToolBar并创建一个自定义动画,将其移动到屏幕的底部。但这很黑。我正在寻找一个更优雅的解决方案。当键盘被解除时,可以让我决定如何处理输入附件视图。

5 个答案:

答案 0 :(得分:52)

它是这样做的:

将您的UIToolbar分配给视图控制器中的属性:

@property (strong, nonatomic) UIToolbar *inputAccessoryToolbar;

在顶视图控制器中,添加以下方法:

- (BOOL)canBecomeFirstResponder{

    return YES;

}

- (UIView *)inputAccessoryView{

    return self.inputAccessoryToolbar;

}

然后(可选,因为通常不需要),只要键盘被隐藏,只需致电:

[self becomeFirstResponder];

这样,您的inputAccessoryToolbar将成为您的视图控制器和文本视图的输入附件视图。

答案 1 :(得分:7)

我最终得到的UIToolBar未被指定为输入附件视图,并在UIKeyboardWillShowNotification / UIKeyboardWillHideNotification

上下滑动

答案 2 :(得分:4)

添加到@ arik的回答,这是Swift版本:

class ViewController: UIViewController {

  @IBOutlet var textField: UITextField!      

  // Input Accessory View
  private var inputAccessoryToolbar: UIToolBar?
  override func canBecomeFirstResponder() -> Bool {
    return true
  }
  override var inputAccessoryView: UIView? {
    return inputAccessoryToolbar
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    inputAccessoryToolbar = UIToolbar(frame: CGRectMake(0, 0, view.frame.size.width, 50))
    textField.inputAccessoryView = inputAccessoryToolbar
  }

  // UITextFieldDelegate
  func textFieldShouldReturn(textField: UITextField) -> Bool {
    becomeFirstResponder()
    return true
  }
}

感谢干净的解决方案!

答案 3 :(得分:2)

根据之前的答案更新到Swift 4。如果您通过storyboards添加工具栏,则可以执行此操作

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    @IBOutlet var toolbar: UIToolbar!

    override var canBecomeFirstResponder: Bool {
        get {
            return true
        }
    }

    override var inputAccessoryView: UIView {
        get {
            return self.toolbar
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        textField.inputAccessoryView = toolbar
    }
}

在这种情况下,只要文本字段重新响应第一个响应者,它就会将第一个响应者默认为主视图。请记住,如果有多个UI元素并且第一个响应者在辞职后默认为不受欢迎的视图,您可能希望显式重新签署第一个响应者,并将主视图设置为第一响应者。

答案 4 :(得分:0)

您可能还需要使用inputAccessoryView来解决该错误,因为它不尊重安全区域的边距,因此不能为iPhone X上的归位指示符腾出空间:iPhone X how to handle View Controller inputAccessoryView?

当您从xib获得UIToolbar时,并且还使用该UIToolbar作为文本字段的inputAccessoryView时,我找到了最简单的解决方案,即当您从覆盖的inputAccessoryView返回工具栏时将其嵌入UIView中,并包含的UIView比safeAreaInsets.bottom高。 (其他解决方案建议将工具栏的底部限制为子类中的安全区域,但这会导致约束冲突,并且还意味着工具栏下方的区域是错误的颜色。)但是,您还必须记住该文本即使屏幕上没有键盘(例如,如果有外部键盘),该字段也可以具有焦点,因此在这种情况下,您还需要将文本视图的inputAccessoryView更改为此工具栏-UIView中。实际上,仅使用包含视图并适当调整其大小可能会使事情变得更简单。无论如何,这是我对inputAccessoryView的覆盖:

    override var inputAccessoryView: UIView? {

    if toolbarContainerView == nil {

        let frame=CGRect(x: toolBar.frame.minX, y: toolBar.frame.minY, width: toolbar.frame.width, height: toolBar.frame.height+view.safeAreaInsets.bottom)

        toolbarContainerView = UIView(frame: frame)

    }

    if (toolbar.superview != toolbarContainerView) {

        //this is set to false when the toolbar is used above the keyboard without the container view

        //we need to set it to true again or else the toolbar will appear at the very top of the window instead of the bottom if the keyboard has previously been shown.

        toolbar.translatesAutoresizingMaskIntoConstraints=true

        toolbarContainerView?.addSubview(toolbar)

    }

    return toolbarContainerView

}

在这种情况下,也可以重写viewSafeAreaInsetsDidChange来调整toolbarContainerView的大小。