LoginSignup
3
3

More than 3 years have passed since last update.

UIToolBarに上下ボタンや完了ボタンをつけるExtension

Last updated at Posted at 2020-11-16

はじめに

ある入力フォームで、キーボードの上に、上下ボタンや完了ボタンがついているのをよく見かけます。そういう気遣いほんとありがたい :hugging:
今回は、一文追加するだけで、それらを実装してくれるExtensionを作ってみたのでそれを紹介します。

実装後イメージ

完了ボタンのみ

uitoolbar_done.gif

上下ボタンと完了ボタン

uitoolbar_updowndone.gif

使い方

完了ボタンのみ

override func viewDidLoad() {
    super.viewDidLoad()
    // 対象のテキストフィールドがアクティブなとき、キーボードのツールバーに、完了ボタンを設定する。
    addPreviousNextableDoneButtonOnKeyboard(textFields: [textField1], previousNextable: false)
}

上下ボタンと完了ボタン

override func viewDidLoad() {
    super.viewDidLoad()
    // 対象のテキストフィールドがアクティブなとき、キーボードのツールバーに、前後ボタンや完了ボタンを設定する。
    addPreviousNextableDoneButtonOnKeyboard(textFields: [textField2, textField3], previousNextable: true)
}

Extension のコード全体

なお、ここに載せているコードは、以下のGistで公開しています。
mnaruse/ViewController+ToolBar.swift


//
//  ViewController+ToolBar.swift
//  KeyboardUpDownSample
//
//  Created by Miharu Naruse on 2020/11/15.
//

// 参考元サイト
// - URL:: https://stackoverflow.com/questions/14148276/toolbar-with-previous-and-next-for-keyboard-inputaccessoryview

import Foundation
import UIKit

extension UIViewController {
    /// 対象のテキストフィールドがアクティブなとき、キーボードのツールバーに、前後ボタンや完了ボタンを設定する処理。
    /// - Parameters:
    ///   - textFields: 設定したいテキストフィールドの配列
    ///   - previousNextable: 前後ボタンを有効にするか否か
    ///
    /// 使い方
    /// =============================================
    ///     // テキストフィールドのキーボードのツールバーの設定
    ///     addPreviousNextableDoneButtonOnKeyboard(textFields: [textField1], previousNextable: false)
    ///     addPreviousNextableDoneButtonOnKeyboard(textFields: [textField2, textField3], previousNextable: true)
    ///
    func addPreviousNextableDoneButtonOnKeyboard(textFields: [UITextField], previousNextable: Bool = false) {
        for (index, textField) in textFields.enumerated() {
            // テキストフィールドごとにループ処理を行う。
            let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
            toolBar.barStyle = .default
            /// バーボタンアイテム
            var items = [UIBarButtonItem]()

            // MARK: 前後ボタンの設定

            if previousNextable {
                // 前後ボタンが有効な場合
                /// 上矢印ボタン
                let previousButton = UIBarButtonItem(image: UIImage(systemName: "chevron.up"), style: .plain, target: self, action: nil)
                if textField == textFields.first {
                    // 設定したいテキストフィールドの配列のうち、一番上のテキストフィールドの場合、不活性化させる。
                    previousButton.isEnabled = false
                } else {
                    // 上記以外の場合
                    // 1つ前のテキストフィールドをターゲットに設定する。
                    previousButton.target = textFields[index - 1]
                    // ターゲットにフォーカスを当てる。
                    previousButton.action = #selector(UITextField.becomeFirstResponder)
                }

                /// 固定スペース
                let fixedSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: self, action: nil)
                fixedSpace.width = 8

                /// 下矢印ボタン
                let nextButton = UIBarButtonItem(image: UIImage(systemName: "chevron.down"), style: .plain, target: self, action: nil)
                if textField == textFields.last {
                    // 設定したいテキストフィールドの配列のうち、一番下のテキストフィールドの場合、不活性化させる。
                    nextButton.isEnabled = false
                } else {
                    // 上記以外の場合
                    // 1つ後のテキストフィールドをターゲットに設定する。
                    nextButton.target = textFields[index + 1]
                    // ターゲットにフォーカスを当てる。
                    nextButton.action = #selector(UITextField.becomeFirstResponder)
                }

                // バーボタンアイテムに前後ボタンを追加する。
                items.append(contentsOf: [previousButton, fixedSpace, nextButton])
            }

            // MARK: 完了ボタンの設定

            let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
            let doneButton = UIBarButtonItem(title: "完了", style: .done, target: view, action: #selector(UIView.endEditing))
            // バーボタンアイテムに完了ボタンを追加する。
            items.append(contentsOf: [flexSpace, doneButton])

            toolBar.setItems(items, animated: false)
            toolBar.sizeToFit()

            textField.inputAccessoryView = toolBar
        }
    }
}

参考記事

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3