Добавьте представление поверх клавиатуры с помощью InputAccessoryView swift

Я пытаюсь добавить uiview, чтобы всегда быть над клавиатурой. Я сделал это сначала с KeyboardWillShow/Hide, но это не охватывает все случаи, и я пытаюсь использовать inputAccesoryView. вот что я попробовал:

private var accessoryView = UIView(frame: CGRectZero)

class ViewController : UIViewController {

var myView: customUIView

override var inputAccessoryView: UIView {
    return accessoryView
}

override func canBecomeFirstResponder() -> Bool {
    return true
}

override func viewDidLoad() {
   super.viewDidLoad()
   accessoryView = myView
}
}

Я получаю следующую ошибку:

Завершение приложения из-за необработанного исключения 'UIViewControllerHierarchyInconsistency', причина: 'дочернее представление controller: UICompatibilityInputViewController должен иметь родительское представление контроллер: MyViewController, но запрошенный родительский элемент: UIInputWindowController: '

любая помощь будет оценена!

Ответ 1

Чтобы получить представление о клавиатуре, сам код довольно прост. Код, который вы опубликовали, неверен, попробуйте это (обратите внимание, что вы должны подключить textField к UITextField в раскадровке):

@IBOutlet weak var textField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()

    let customView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 44))
    customView.backgroundColor = UIColor.red
    textField.inputAccessoryView = customView
}

Ответ 2

Подробнее

  • Xcode 9.2, swift 4
  • Xcode 10.2.1 (10E1001), 11.0 (11A420a), Swift 5

Решение

KeyboardToolbarButton

import UIKit

enum KeyboardToolbarButton: Int {

    case done = 0
    case cancel
    case back, backDisabled
    case forward, forwardDisabled

    func createButton(target: Any?, action: Selector?) -> UIBarButtonItem {
        var button: UIBarButtonItem!

        switch self {
        case .back:
            button = UIBarButtonItem(title: "back", style: .plain, target: target, action: action)
        case .backDisabled:
            button = UIBarButtonItem(title: "back", style: .plain, target: target, action: action)
            button.isEnabled = false
        case .forward:
            button = UIBarButtonItem(title: "forward", style: .plain, target: target, action: action)
        case .forwardDisabled:
            button = UIBarButtonItem(title: "forward", style: .plain, target: target, action: action)
            button.isEnabled = false
        case .done:
            button = UIBarButtonItem(title: "done", style: .plain, target: target, action: action)
        case .cancel:
            button = UIBarButtonItem(title: "cancel", style: .plain, target: target, action: action)
        }
        button.tag = rawValue
        return button
    }

    static func detectType(barButton: UIBarButtonItem) -> KeyboardToolbarButton? {
        return KeyboardToolbarButton(rawValue: barButton.tag)
    }
}

KeyboardToolbar

import UIKit

protocol KeyboardToolbarDelegate: class {
    func keyboardToolbar(button: UIBarButtonItem, type: KeyboardToolbarButton, tappedIn toolbar: KeyboardToolbar)
}

class KeyboardToolbar: UIToolbar {

    weak var toolBarDelegate: KeyboardToolbarDelegate?

    init() {
        super.init(frame: CGRect(origin: .zero, size: CGSize(width: UIScreen.main.bounds.width, height: 44)))
        barStyle = UIBarStyle.default
        isTranslucent = true
        isUserInteractionEnabled = true
    }

    func setup(leftButtons: [KeyboardToolbarButton], rightButtons: [KeyboardToolbarButton]) {

        let leftBarButtons = leftButtons.map {
            $0.createButton(target: self, action: #selector(buttonTapped))
        }
        let rightBarButtons = rightButtons.map {
            $0.createButton(target: self, action: #selector(buttonTapped(sender:)))
        }

        let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        setItems(leftBarButtons + [spaceButton] + rightBarButtons, animated: false)
    }

    required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
    @objc func buttonTapped(sender: UIBarButtonItem) {
        guard let type = KeyboardToolbarButton.detectType(barButton: sender) else { return }
        toolBarDelegate?.keyboardToolbar(button: sender, type: type, tappedIn: self)
    }
}

Полный пример использования

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        createTextField(frame: CGRect(x: 50, y: 50, width: 200, height: 40), leftButtons: [.backDisabled, .forward], rightButtons: [.cancel])
        createTextField(frame: CGRect(x: 50, y: 120, width: 200, height: 40), leftButtons: [.back, .forwardDisabled], rightButtons: [.done])
    }

    private func createTextField(frame: CGRect, leftButtons: [KeyboardToolbarButton] = [], rightButtons: [KeyboardToolbarButton] = []) {
        let textField = UITextField(frame: frame)
        textField.borderStyle = .roundedRect
        let toolbar = KeyboardToolbar()
        toolbar.toolBarDelegate = self
        toolbar.setup(leftButtons: leftButtons, rightButtons: rightButtons)
        textField.inputAccessoryView = toolbar
        view.addSubview(textField)
    }
}

extension ViewController: KeyboardToolbarDelegate {
   func keyboardToolbar(button: UIBarButtonItem, type: KeyboardToolbarButton, tappedIn toolbar: KeyboardToolbar) {
        print("Tapped button type: \(type)")
    }
}

Результаты

enter image description here


enter image description here


enter image description here

Ответ 3

Изменения, внесенные в ваш код:

  • Дайте accessoryView высоту
  • Удалить var myView: customUIView и весь viewDidLoad() переопределить

Ответ 4

Попробуй это.

override var inputAccessoryView: UIView? {
    get {
       return containerView
    }
}
override var canBecomeFirstResponder: Bool {
   return true
}