@ -484,6 +484,7 @@ class CaptioningToolbar: UIView, UITextViewDelegate {
 
		
	
		
			
				    private  let  sendButton :  UIButton 
 
		
	
		
			
				    private  let  textView :  UITextView 
 
		
	
		
			
				    private  let  bottomGradient :  GradientView 
 
		
	
		
			
				    private  let  lengthLimitLabel :  UILabel 
 
		
	
		
			
				
 
		
	
		
			
				    //   L a y o u t   C o n s t a n t s 
 
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -523,6 +524,7 @@ class CaptioningToolbar: UIView, UITextViewDelegate {
 
		
	
		
			
				        self . bottomGradient  =  GradientView ( from :  UIColor . clear ,  to :  UIColor . black ) 
 
		
	
		
			
				        self . textView  =   MessageTextView ( ) 
 
		
	
		
			
				        self . textViewHeight  =  kMinTextViewHeight 
 
		
	
		
			
				        self . lengthLimitLabel  =  UILabel ( ) 
 
		
	
		
			
				
 
		
	
		
			
				        super . init ( frame :  CGRect . zero ) 
 
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -560,12 +562,24 @@ class CaptioningToolbar: UIView, UITextViewDelegate {
 
		
	
		
			
				        //   I n c r e a s e   h i t   a r e a   o f   s e n d   b u t t o n 
 
		
	
		
			
				        sendButton . contentEdgeInsets  =  UIEdgeInsets ( top :  6 ,  left :  8 ,  bottom :  6 ,  right :  8 ) 
 
		
	
		
			
				
 
		
	
		
			
				        //   L e n g t h   L i m i t   L a b e l   s h o w n   w h e n   t h e   u s e r   i n p u t s   t o o   l o n g   o f   a   m e s s a g e 
 
		
	
		
			
				        lengthLimitLabel . textColor  =  . white 
 
		
	
		
			
				        lengthLimitLabel . text  =  NSLocalizedString ( " ATTACHMENT_APPROVAL_CAPTION_LENGTH_LIMIT_REACHED " ,  comment :  " One line label indicating the user can add no more text to the attachment caption. " ) 
 
		
	
		
			
				        lengthLimitLabel . textAlignment  =  . center 
 
		
	
		
			
				
 
		
	
		
			
				        //   A d d   s h a d o w   i n   c a s e   o v e r l a y e d   o n   w h i t e   c o n t e n t 
 
		
	
		
			
				        lengthLimitLabel . layer . shadowColor  =  UIColor . black . cgColor 
 
		
	
		
			
				        lengthLimitLabel . layer . shadowOffset  =  CGSize ( width :  0.0 ,  height :  0.0 ) 
 
		
	
		
			
				        lengthLimitLabel . layer . shadowOpacity  =  0.8 
 
		
	
		
			
				        self . lengthLimitLabel . isHidden  =  true 
 
		
	
		
			
				
 
		
	
		
			
				        let  contentView  =  UIView ( ) 
 
		
	
		
			
				        addSubview ( contentView ) 
 
		
	
		
			
				        contentView . autoPinEdgesToSuperviewEdges ( ) 
 
		
	
		
			
				        contentView . addSubview ( bottomGradient ) 
 
		
	
		
			
				        contentView . addSubview ( sendButton ) 
 
		
	
		
			
				        contentView . addSubview ( textView ) 
 
		
	
		
			
				        contentView . addSubview ( lengthLimitLabel ) 
 
		
	
		
			
				
 
		
	
		
			
				        //   L a y o u t 
 
		
	
		
			
				        let  kToolbarMargin :  CGFloat  =  8 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -597,6 +611,12 @@ class CaptioningToolbar: UIView, UITextViewDelegate {
 
		
	
		
			
				        sendButton . setContentHuggingHigh ( ) 
 
		
	
		
			
				        sendButton . setCompressionResistanceHigh ( ) 
 
		
	
		
			
				
 
		
	
		
			
				        lengthLimitLabel . autoPinEdge ( toSuperviewMargin :  . left ) 
 
		
	
		
			
				        lengthLimitLabel . autoPinEdge ( toSuperviewMargin :  . right ) 
 
		
	
		
			
				        lengthLimitLabel . autoPinEdge ( . bottom ,  to :  . top ,  of :  textView ,  withOffset :  - 6 ) 
 
		
	
		
			
				        lengthLimitLabel . setContentHuggingHigh ( ) 
 
		
	
		
			
				        lengthLimitLabel . setCompressionResistanceHigh ( ) 
 
		
	
		
			
				
 
		
	
		
			
				        let  bottomGradientHeight  =  ScaleFromIPhone5 ( 100 ) 
 
		
	
		
			
				        bottomGradient . autoSetDimension ( . height ,  toSize :  bottomGradientHeight ) 
 
		
	
		
			
				        bottomGradient . autoPinEdgesToSuperviewEdges ( with :  . zero ,  excludingEdge :  . top ) 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -609,19 +629,28 @@ class CaptioningToolbar: UIView, UITextViewDelegate {
 
		
	
		
			
				    //   MARK:   -   U I T e x t V i e w D e l e g a t e 
 
		
	
		
			
				
 
		
	
		
			
				    public  func  textViewDidChange ( _  textView :  UITextView )  { 
 
		
	
		
			
				        //   c o m p u t e   n e w   h e i g h t   a s s u m i n g   w i d t h   i s   u n c h a n g e d 
 
		
	
		
			
				        let  currentSize  =  textView . frame . size 
 
		
	
		
			
				        let  newHeight  =  clampedTextViewHeight ( fixedWidth :  currentSize . width ) 
 
		
	
		
			
				        updateHeight ( textView :  textView ) 
 
		
	
		
			
				    } 
 
		
	
		
			
				
 
		
	
		
			
				        if  newHeight  !=  self . textViewHeight  { 
 
		
	
		
			
				            Logger . debug ( " \( self . logTag )  TextView height changed:  \( self . textViewHeight )  ->  \( newHeight ) " ) 
 
		
	
		
			
				            self . textViewHeight  =  newHeight 
 
		
	
		
			
				            self . textViewHeightConstraint ? . constant  =  textViewHeight 
 
		
	
		
			
				            self . invalidateIntrinsicContentSize ( ) 
 
		
	
		
			
				    public  func  textView ( _  textView :  UITextView ,  shouldChangeTextIn  range :  NSRange ,  replacementText  text :  String )  ->  Bool  { 
 
		
	
		
			
				
 
		
	
		
			
				        //   L i m i t   c a p t i o n   c h a r a c t e r   c o u n t .   W e   d o   t h i s   i n   c h a r a c t e r s ,   n o t   b y t e s . 
 
		
	
		
			
				        //   T h i s   c h a r a c t e r   l i m i t   w i l l   b e   s a f e l y   b e l o w   o u r   b y t e   l i m i t   ( 1 6 k )   f o r   a l m o s t   a l l   u s e s . 
 
		
	
		
			
				        //   B e c a u s e   t h e   c a p t i o n i n g   i n t e r f a c e   d o e s n ' t   a l l o w   n e w l i n e s ,   i n   p r a c t i c e   d e s i g n   p r e s s u r e s   u s e r s   t o   l e a v e   r e l a t i v e l y   s h o r t   c a p t i o n s . 
 
		
	
		
			
				        let  maxCharacterCount  =  2000 
 
		
	
		
			
				        guard  textView . text . count  +  text . count  -  range . length  <=  maxCharacterCount  else  { 
 
		
	
		
			
				            self . lengthLimitLabel . isHidden  =  false 
 
		
	
		
			
				            //   A c c e p t   a s   m u c h   o f   t h e   i n p u t   a s   w e   c a n 
 
		
	
		
			
				            let  remainingSpace  =  maxCharacterCount  -  textView . text . count 
 
		
	
		
			
				            if  ( remainingSpace )  >  0  { 
 
		
	
		
			
				                let  acceptableAddition  =  text . substring ( to :  text . startIndex . advanced ( by :  remainingSpace ) ) 
 
		
	
		
			
				                textView . text  =  " \( textView . text  ? ?  " " ) \( acceptableAddition ) " 
 
		
	
		
			
				                updateHeight ( textView :  textView ) 
 
		
	
		
			
				            } 
 
		
	
		
			
				            return  false 
 
		
	
		
			
				        } 
 
		
	
		
			
				        self . lengthLimitLabel . isHidden  =  true 
 
		
	
		
			
				
 
		
	
		
			
				    public  func  textView ( _  textView :  UITextView ,  shouldChangeTextIn  range :  NSRange ,  replacementText  text :  String )  ->  Bool  { 
 
		
	
		
			
				        //   T h o u g h   w e   c a n   w r a p   t h e   t e x t ,   w e   d o n ' t   w a n t   t o   e n c o u r a g e   m u l t l i n e   c a p t i o n s ,   p l u s   a   " d o n e "   b u t t o n 
 
		
	
		
			
				        //   a l l o w s   t h e   u s e r   t o   g e t   t h e   k e y b o a r d   o u t   o f   t h e   w a y   w h i l e   i n   t h e   a t t a c h m e n t   a p p r o v a l   v i e w . 
 
		
	
		
			
				        if  text  = =  " \n "  { 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -642,6 +671,19 @@ class CaptioningToolbar: UIView, UITextViewDelegate {
 
		
	
		
			
				
 
		
	
		
			
				    //   MARK:   -   H e l p e r s 
 
		
	
		
			
				
 
		
	
		
			
				    private  func  updateHeight ( textView :  UITextView )  { 
 
		
	
		
			
				        //   c o m p u t e   n e w   h e i g h t   a s s u m i n g   w i d t h   i s   u n c h a n g e d 
 
		
	
		
			
				        let  currentSize  =  textView . frame . size 
 
		
	
		
			
				        let  newHeight  =  clampedTextViewHeight ( fixedWidth :  currentSize . width ) 
 
		
	
		
			
				
 
		
	
		
			
				        if  newHeight  !=  self . textViewHeight  { 
 
		
	
		
			
				            Logger . debug ( " \( self . logTag )  TextView height changed:  \( self . textViewHeight )  ->  \( newHeight ) " ) 
 
		
	
		
			
				            self . textViewHeight  =  newHeight 
 
		
	
		
			
				            self . textViewHeightConstraint ? . constant  =  textViewHeight 
 
		
	
		
			
				            self . invalidateIntrinsicContentSize ( ) 
 
		
	
		
			
				        } 
 
		
	
		
			
				    } 
 
		
	
		
			
				
 
		
	
		
			
				    private  func  clampedTextViewHeight ( fixedWidth :  CGFloat )  ->  CGFloat  { 
 
		
	
		
			
				        let  contentSize  =  textView . sizeThatFits ( CGSize ( width :  fixedWidth ,  height :  CGFloat . greatestFiniteMagnitude ) ) 
 
		
	
		
			
				        return  Clamp ( contentSize . height ,  kMinTextViewHeight ,  maxTextViewHeight )