как я могу увеличить высоту inputAccessoryView

Я потратил на это несколько дней, но решения не видно.

У меня есть inputAccessoryView, который состоит из UIView, содержащего textView и две кнопки. Поведение inputAccessoryView соответствует ожиданиям и работает нормально во всех случаях, кроме одного.

Когда высота textView увеличивается, я пытаюсь увеличить высоту inputAccessoryView на ту же величину. Когда я переопределяю высоту inputAccessoryView в textViewDidChange, inputAccessoryView увеличивает высоту над клавиатурой вниз, а не вверх.

Я пробовал много разных предложений от SO, но ничего не сработало. Я предполагаю, что это автоматически добавленное NSLayoutConstraint из inputAccessoryView, но я понятия не имею, как изменить это значение в swift и iOS 8.3.

func textViewDidChange(textView: UITextView) {

    var contentSize = messageTextView.sizeThatFits(CGSizeMake(messageTextView.frame.size.width, CGFloat.max))

    inputAccessoryView.frame.size.height = contentSize.height + 16

}

добавление

inputAccessoryView.setTranslatesAutoresizingMaskIntoConstraints(true)

к приведенному выше коду помогает, и высота inputAccessoryView правильно увеличивается вверх, однако я получаю сообщение «Невозможно одновременно удовлетворить ограничения для нескольких ограничений», и очень сложно идентифицировать нарушителей. Также я получаю странный эффект от того, что textView создает дополнительное пространство ниже для каждого второго экземпляра новой строки.

Спасибо.


person alionthego    schedule 05.08.2015    source источник
comment
я заметил, что первый вызов textViewDidChange правильно изменяет размер inputAccessoryView без строки setTranslatesAutoresizingMaskIntoConstraints, но последующие вызовы не имеют никакого эффекта. Интересно, почему это так и как я могу каждый раз восстанавливать его в исходное состояние?   -  person alionthego    schedule 05.08.2015


Ответы (2)


Чтобы увеличить представление входных аксессуаров по вертикали, вы просто устанавливаете его autoresizingMask = .flexibleHeight, вычисляете его intrinsicContentSize и позволяете фреймворку делать все остальное.

Код:

class InputAccessoryView: UIView, UITextViewDelegate {

    let textView = UITextView()

    override init(frame: CGRect) {
        super.init(frame: frame)

        // This is required to make the view grow vertically
        self.autoresizingMask = UIView.AutoresizingMask.flexibleHeight

        // Setup textView as needed
        self.addSubview(self.textView)
        self.textView.translatesAutoresizingMaskIntoConstraints = false
        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[textView]|", options: [], metrics: nil, views: ["textView": self.textView]))
        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[textView]|", options: [], metrics: nil, views: ["textView": self.textView]))

        self.textView.delegate = self

        // Disabling textView scrolling prevents some undesired effects,
        // like incorrect contentOffset when adding new line,
        // and makes the textView behave similar to Apple's Messages app
        self.textView.isScrollEnabled = false
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override var intrinsicContentSize: CGSize {
        // Calculate intrinsicContentSize that will fit all the text
        let textSize = self.textView.sizeThatFits(CGSize(width: self.textView.bounds.width, height: CGFloat.greatestFiniteMagnitude))
        return CGSize(width: self.bounds.width, height: textSize.height)
    }

    // MARK: UITextViewDelegate

    func textViewDidChange(_ textView: UITextView) {
        // Re-calculate intrinsicContentSize when text changes
        self.invalidateIntrinsicContentSize()
    }

}
person maxkonovalov    schedule 18.09.2015
comment
Спасибо за очень лаконичный ответ. - person alionthego; 18.09.2015
comment
Как вы узнали, как это сделать? Это похоже на волшебство, как это работает! Я хотел бы знать процесс, который вы прошли, чтобы изучить эту технику. - person Xavier L.; 08.02.2018
comment
в iOS 11 этот метод работает только тогда, когда введенный текст приводит к увеличению UITextBox. При уменьшении размер остается прежним. - person Albert Bori; 29.08.2018
comment
На всякий случай, если кто-то здесь новичок, это override var intrinsicContentSize: CGSize { ... } и autoresizingMask = .flexibleHeight в текущей быстрой версии (4.2). Отличный ответ кстати - person gujci; 14.12.2018

Перенесемся в 2020 год, вы можете просто сделать следующее, все остальное так же, как в ответе максконовалова.

override var intrinsicContentSize: CGSize {
    return .zero
}

// MARK: UITextViewDelegate

func textViewDidChange(_ textView: UITextView) {
    sizeToFit()
}
person Jack Guo    schedule 14.03.2020