37

私がやろうとしているのは、iPad の Safari の「ページで検索」検索機能に似たものを作成することです。

にいくつかのアイテムを入れて を使用してUIToolbarおり、 に設定してキーボードに取り付けinputAccessoryViewましたUITextField。魔法のように機能しますが、理解できないことが1つあります。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 でホーム インジケーター用のスペースを作成しないというバグを回避する必要がある場合もあります。

xib から UIToolbar があり、その UIToolbar をテキスト フィールドの inputAccessoryView として使用している場合の最も簡単な解決策は、オーバーライドされた inputAccessoryView からツールバーを返すときにツールバーを UIView に埋め込み、それを含む UIView を高くすることです。 safeAreaInsets.bottom によって。(他の解決策では、ツールバーの下部をサブクラスの安全な領域に制限することを提案していますが、これは制約の競合につながり、ツールバーの下の領域が間違った色になることも意味します。) ただし、テキストが画面にキーボードがない場合 (たとえば、外部キーボードがある場合) でもフィールドにフォーカスがある可能性があるため、その場合もテキスト ビューの inputAccessoryView をこの toolbar-within-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

}

その場合も、viewSafeAreaInsetsDidChange をオーバーライドして、toolbarContainerView のサイズを調整することをお勧めします。

于 2018-07-22T18:16:10.970 に答える