37

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

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

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

4

5 回答 5

61

它是这样完成的:

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

@property (strong, nonatomic) UIToolbar *inputAccessoryToolbar;

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

- (BOOL)canBecomeFirstResponder{

    return YES;

}

- (UIView *)inputAccessoryView{

    return self.inputAccessoryToolbar;

}

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

[self becomeFirstResponder];

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

于 2014-07-20T21:30:41.340 回答
8

我最终UIToolBar没有将其分配为输入附件视图,然后上下滑动UIKeyboardWillShowNotification / UIKeyboardWillHideNotification

于 2012-07-05T11:59:46.083 回答
5

根据先前的答案更新到 Swift 4。如果您通过情节提要添加工具栏,您可以这样做

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 元素并且第一响应者在辞职后默认为不想要的视图,您可能希望显式辞职第一响应者,并将主视图设置为第一响应者。

于 2018-03-06T09:07:40.257 回答
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
  }
}

感谢您提供干净的解决方案!

于 2016-06-26T06:37:51.147 回答
1

您可能还需要解决 inputAccessoryView 不尊重安全区域边距的错误,因此没有为 iPhone X 上的主页指示器腾出空间:iPhone X 如何处理视图控制器 inputAccessoryView?

当您有来自 xib 的 UIToolbar 并且您还使用该 UIToolbar 作为文本字段的 inputAccessoryView 时,我找到了最简单的解决方案,即当您从覆盖的 inputAccessoryView 返回工具栏时,将工具栏嵌入 UIView 中,并使包含的 UIView 更高通过 safeAreaInsets.bottom。(其他解决方案建议将工具栏的底部约束到子类中的安全区域,但这会导致约束冲突,也意味着工具栏下的区域颜色错误。)但是,您还必须记住,文本即使屏幕上没有键盘(例如,如果有外部键盘),字段也可以具有焦点,因此在这种情况下,您也需要将文本视图的 inputAccessoryView 更改为此工具栏-in-a-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

}

It would probably be a good idea to override viewSafeAreaInsetsDidChange to adjust the size of toolbarContainerView in that case, too.

于 2018-07-22T18:16:10.970 回答