Basically I am trying to create a resizing UITextView within a inputAccessoryView property.
I have a viewController with the method canBecomeFirstResponder returning tru
SWIFT 5 Solution
If anyone has been trying to find for a solution in stackoverflow like me for input accessory view, I have made a simple project demo for a dynamically resizing input accessory with UITextView. It also comes with a tappable button on top of the UITextView to demonstrate added views on top of the Input Accessory View. All of these are loaded in a XIB for easy customisation. Written in Swift 5, and also takes care of the safe area for X devices.
class InputAccessoryView: UIView, UITextViewDelegate {
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var accessoryButtonViewHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var accessoryButtonView: UIView!
// MARK: - Init
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
private func setup() {
let view = self.viewFromNibForClass()
view?.frame = self.bounds
view?.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.accessoryButtonViewHeightConstraint.constant = 0
if let view = view {
self.addSubview(view)
self.textView.translatesAutoresizingMaskIntoConstraints = false
}
}
override func didMoveToWindow() {
super.didMoveToWindow()
if let window = self.window {
self.bottomAnchor.constraint(lessThanOrEqualTo: window.safeAreaLayoutGuide.bottomAnchor).isActive = true
}
}
private func viewFromNibForClass() -> UIView? {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil).first as? UIView
return view
}
func textViewDidChange(_ textView: UITextView) {
self.accessoryButtonViewHeightConstraint.constant = 40
self.accessoryButtonView.alpha = 1
self.updateHeight(textView.contentSize.height + 20 + self.accessoryButtonViewHeightConstraint.constant)
}
private func updateHeight(_ height: CGFloat) {
for constraint in self.constraints where constraint.firstAttribute == .height {
constraint.constant = height
}
}
@IBAction func accessoryButtonTouchUpInside(_ sender: Any) {
let height = self.frame.size.height - 40
self.updateHeight(height)
self.accessoryButtonViewHeightConstraint.constant = 0
}
}
Here is an example of the usage: https://github.com/jaysalvador/InputAccessoryView