Hi. I am trying to figure out how to do a simple thing, but all research that I have done so far has not clarified what the proper way to do it is. I am adding a UITextView that should expand while I am typing upwards and then enable scrolling when the maximum height is reached. Instead, my UITextView is expanding downwards. My code:
overridefunc didMove(to view: SKView)
{
txtMessage = UITextView()
txtMessage.font = UIFont.systemFont(ofSize: 16)
txtMessage.layer.cornerRadius = 5
txtMessage.autocorrectionType = UITextAutocorrectionType.no
txtMessage.keyboardType = UIKeyboardType.default
txtMessage.returnKeyType = UIReturnKeyType.done
txtMessage.isScrollEnabled = false
txtMessage.delegate = self
self.view!.addSubview(txtMessage)
registerForKeyboardNotifications()
}
func textViewDidChange(_ textView: UITextView)
{
let fixedWidth = textView.frame.size.width
// Changing height of the message UITextView
let newSize = textView.sizeThatFits(CGSize.init(width: fixedWidth, height: CGFloat(MAXFLOAT)))
var newFrame = textView.frame
newFrame.size = CGSize.init(width: CGFloat(fmaxf(Float(newSize.width), Float(fixedWidth))), height: newSize.height)
txtMessage.frame = CGRect(origin: textView.frame.origin, size: CGSize(width: newFrame.width, height: newFrame.height))
}
func registerForKeyboardNotifications()
{
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver( self,
selector: #selector(GameScene.keyboardWillShow(_:)),
name: UIResponder.keyboardWillShowNotification,
object: nil )
notificationCenter.addObserver( self,
selector: #selector(GameScene.keyboardWillBeHidden(_:)),
name: UIResponder.keyboardWillHideNotification,
object: nil)
}
func unregisterForKeyboardNotifications()
{
let notificationCenter = NotificationCenter.default
notificationCenter.removeObserver( self,
name: UIResponder.keyboardWillShowNotification,
object: nil)
notificationCenter.removeObserver( self,
name: UIResponder.keyboardWillHideNotification,
object: nil)
}
@objc func keyboardWillShow(_ notification: Notification)
{
let txtMessageViewHeight : CGFloat = 41
if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue
{
let duration:TimeInterval = (notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
keyboardHeight = keyboardFrame.cgRectValue.height
let viewHeight = keyboardHeight + txtMessageViewHeight
self.txtMessage.frame.origin.y -= viewHeight
self.txtMessage.layoutIfNeeded()
}
}
Thank you!
I am really surprised.
Line 6, why do you use
txtMessage.frame
and not textView.frame ?
Could you also draw the border to see what happens and add some print:
func textViewDidChange(_ textView: UITextView) {
let fixedWidth = textView.frame.size.width
// Changing height of the message UITextView
let newSize = textView.sizeThatFits(CGSize.init(width: fixedWidth, height: CGFloat(MAXFLOAT)))
var newFrame = textView.frame
print("textView.frame", textView.frame)
newFrame.size = CGSize.init(width: CGFloat(fmaxf(Float(newSize.width), Float(fixedWidth))), height: newSize.height)
var newOrigin = textView.frame.origin
newOrigin.y -= (newSize.height - newFrame.size.height)
textView.frame = CGRect(origin: textView.frame.origin, size: CGSize(width: newFrame.width, height: newFrame.height))
print("New textView.frame", textView.frame)
txtMessage.layer.borderColor = UIColor.red.cgColor
txtMessage.layer.borderWidth = 1.0
}