 
 import UIKit
 
+/// The type of the block which contains user defined actions that will run during the height change.
+public typealias HeightChangeUserActionsBlockType = ((oldHeight: CGFloat, newHeight: CGFloat) -> Void)
+
 /// The `RSKGrowingTextViewDelegate` protocol extends the `UITextViewDelegate` protocol by providing a set of optional methods you can use to receive messages related to the change of the height of `RSKGrowingTextView` objects.
 @objc public protocol RSKGrowingTextViewDelegate: UITextViewDelegate {
     ///

        let newHeight = calculatedHeight
        
        if oldHeight != newHeight {
            growingTextViewDelegate?.growingTextView?(self, willChangeHeightFrom: oldHeight, to: newHeight)
            
            if animated {
                UIView.animateWithDuration(
                    heightChangeAnimationDuration,
                    delay: 0.0,
                    options: [.AllowUserInteraction, .BeginFromCurrentState],
                    animations: { [unowned self] () -> Void in
                        self.setHeight(newHeight)
                        self.heightChangeUserActionsBlock?(growingTextViewHeightBegin: oldHeight, growingTextViewHeightEnd: newHeight)
                        
                        self.superview?.layoutIfNeeded()
                    },
                    completion: { [unowned self] (finished: Bool) -> Void in
                        self.layoutManager.ensureLayoutForTextContainer(self.textContainer)
                        self.scrollToVisibleCaretIfNeeded()
                        
                        self.growingTextViewDelegate?.growingTextView?(self, didChangeHeightFrom: oldHeight, to: newHeight)
                    }
                )
            } else {
                setHeight(newHeight)
                heightChangeUserActionsBlock?(growingTextViewHeightBegin: oldHeight, growingTextViewHeightEnd: newHeight)
                
                superview?.layoutIfNeeded()
                layoutManager.ensureLayoutForTextContainer(textContainer)
                scrollToVisibleCaretIfNeeded()
                
                growingTextViewDelegate?.growingTextView?(self, didChangeHeightFrom: oldHeight, to: newHeight)
            }
        } else {
            scrollToVisibleCaretIfNeeded()


/// A light-weight UITextView subclass that automatically grows and shrinks based on the size of user input and can be constrained by maximum and minimum number of lines.
@IBDesignable public class RSKGrowingTextView: RSKPlaceholderTextView {
    
    // MARK: - Private Properties
    
    private var calculatedHeight: CGFloat {
