I have set up a subclass of UITextView
which expands and shrinks to fit the text as the user types, called FlexibleText. I also have a Pinch Gesture Recognizer on this text view allowing users to scale it up and down.
However, when I pinch to scale the text view down, then try to edit it again, after typing any character the UITextContainerView
scales down inside the text view, cutting off some of the text.
I'd be really grateful for any help in figuring this out! Here is my code:
import UIKit
class ViewController: UIViewController, UITextViewDelegate, UIGestureRecognizerDelegate {
class FlexibleText: UITextView {
var horizontalConstraint: NSLayoutConstraint?
var verticalConstraint: NSLayoutConstraint?
var widthConstraint: NSLayoutConstraint?
var heightConstraint: NSLayoutConstraint?
}
var currentTextView = FlexibleText()
var screenWidth = UIScreen.main.bounds.width
var screenHeight = UIScreen.main.bounds.height
override func viewDidLoad() {
super.viewDidLoad()
//add close keyboard recognizer
let closeKeyboardRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
view.addGestureRecognizer(closeKeyboardRecognizer)
let text1 = FlexibleText()
text1.text = "your text"
text1.font = UIFont.systemFont(ofSize: 40)
text1.backgroundColor = UIColor.yellow
text1.frame = CGRect(x: 50, y: 100, width: 250, height: 100)
text1.isScrollEnabled = false
text1.delegate = self
text1.textAlignment = .center
view.addSubview(text1)
// layout
text1.translatesAutoresizingMaskIntoConstraints = false
text1.horizontalConstraint = text1.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0)
text1.horizontalConstraint?.isActive = true
text1.verticalConstraint = text1.topAnchor.constraint(equalTo: view.topAnchor, constant: 100)
text1.verticalConstraint?.isActive = true
text1.widthConstraint = text1.widthAnchor.constraint(equalToConstant: 250)
text1.widthConstraint?.isActive = true
text1.heightConstraint = text1.heightAnchor.constraint(equalToConstant: 100)
text1.heightConstraint?.isActive = true
adjustTextViewHeight(text1)
currentTextView = text1
//add pinch gesture
let pinchGesture = UIPinchGestureRecognizer(target: self, action:#selector(pinchRecognized))
pinchGesture.delegate = self
text1.addGestureRecognizer(pinchGesture)
}
// flexible functions
func textViewDidChange(_ textView: UITextView) {
adjustTextViewHeight(textView)
}
func adjustTextViewHeight(_ textView: UITextView) {
let newSize = textView.sizeThatFits(CGSize(width: screenWidth, height: CGFloat.greatestFiniteMagnitude))
if let currentView = textView as? FlexibleText {
if newSize.width <= screenWidth {
currentView.widthConstraint?.constant = newSize.width
} else if newSize.width > screenWidth {
currentView.widthConstraint?.constant = screenWidth
}
currentView.heightConstraint?.constant = newSize.height
}
self.view.layoutIfNeeded()
}
@objc func dismissKeyboard() {
view.endEditing(true)
}
//pinch gesture
@objc func pinchRecognized(recognizer: UIPinchGestureRecognizer) {
if let view = recognizer.view as? FlexibleText {
if recognizer.state == .changed {
view.transform = view.transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
} else if recognizer.state == .ended {
view.font = UIFont.systemFont(ofSize: 40 * recognizer.scale)
}
adjustTextViewHeight(view)
recognizer.scale = 1.0
}
}
}
Here is an image of before scaling down:
and after:
And a screenshot of the view hierarchy:
Thanks!