Reputation: 638
I've a textfield zone which is supposed to have a flexible height, growing along number of lines you have written.
I would like to listen to it's height's change and then when a new line will be create this listener will say "Hi the height has changed !".
---------- Initial Height ----------
---------- Height has changed !!! ----------
I can't find out a proper way to do this, because addObserver
in swift require a NotificationIdentifier like keyboardWillShow
and here I don't have one like heightWillChange
.
How can I call a function when the height changed ?
Upvotes: 1
Views: 2053
Reputation: 149
extension MyThing: UITextViewDelegate {
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let oldText = textView.text else {
return true
}
let newText = (textView.text as NSString).replacingCharacters(in: range, with: text)
let size = CGSize(width: textView.bounds.width, height: CGFloat.greatestFiniteMagnitude)
let font = textView.font!
let oldTextRect = newText.boundingRect(with: size,
options: .usesLineFragmentOrigin,
attributes: [.font : font],
context: nil)
let newTextRect = oldText.boundingRect(with: size,
options: .usesLineFragmentOrigin,
attributes: [.font : font],
context: nil)
if oldTextRect != newTextRect {
print("Text height changed")
} else {
print("Text height didnt change :(")
}
return true
}
}
Upvotes: 0
Reputation: 15331
You can use KVO. If you're doing this from a view controller you can add observing in viewDidLoad
. For example:
override func viewDidLoad() {
super.viewDidLoad()
self.textField = UITextField(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
self.textField.addObserver(self, forKeyPath: "frame", options: .New, context: nil)
}
Then respond in:
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == "frame" && object === self.textField
{
print(self.textField.frame)
}
}
Then remove observing when your view controller is deinited:
deinit {
self.textField.removeObserver(self, forKeyPath: "frame")
}
Upvotes: 1
Reputation: 6114
Use delegate method of your UITextView
var textViewHeight: CGFloat = 0
func textViewDidChange(textView: UITextView)
{
let newTextViewHeight = textView.frame.size.height
if textViewHeight != newTextViewHeight
{
print("---------- Height has changed !!! ----------")
}
textViewHeight = newTextViewHeight
}
Upvotes: 1