@ -1398,7 +1398,6 @@ class CaptionView: UIView {
placeholderTextView . isEditable = false
placeholderTextView . backgroundColor = . clear
placeholderTextView . keyboardAppearance = Theme . keyboardAppearance
placeholderTextView . font = UIFont . ows_dynamicTypeBody
placeholderTextView . textColor = Theme . darkThemePrimaryColor
@ -1411,7 +1410,7 @@ class CaptionView: UIView {
private lazy var textView : UITextView = {
let textView = UITextView ( )
textView . backgroundColor = . clear
textView . keyboardAppearance = Theme . keyboardAppearance
textView . keyboardAppearance = Theme . dar kThemeK eyboardAppearance
textView . font = UIFont . ows_dynamicTypeBody
textView . textColor = Theme . darkThemePrimaryColor
textView . tintColor = Theme . darkThemePrimaryColor
@ -1529,31 +1528,15 @@ protocol MediaMessageTextToolbarDelegate: class {
class MediaMessageTextToolbar : UIView , UITextViewDelegate {
weak var mediaMessageTextToolbarDelegate : MediaMessageTextToolbarDelegate ?
private let addMoreButton : UIButton
private let sendButton : UIButton
let textView : UITextView
var messageText : String ? {
get { return self . textView . text }
set { self . textView . text = newValue }
}
private lazy var lengthLimitLabel : UILabel = {
let lengthLimitLabel = UILabel ( )
// 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_MESSAGE_LENGTH_LIMIT_REACHED " , comment : " One-line label indicating the user can add no more text to the media message field. " )
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
lengthLimitLabel . isHidden = true
get { return textView . text }
return lengthLimitLabel
} ( )
set {
textView . text = newValue
updatePlaceholderTextViewVisibility ( )
}
}
// L a y o u t C o n s t a n t s
@ -1566,30 +1549,11 @@ class MediaMessageTextToolbar: UIView, UITextViewDelegate {
var textViewHeightConstraint : NSLayoutConstraint !
var textViewHeight : CGFloat
class MessageTextView : UITextView {
// W h e n c r e a t i n g n e w l i n e s , c o n t e n t O f f s e t i s a n i m a t e d , b u t b e c a u s e b e c a u s e
// w e a r e s i m u l t a n e o u s l y r e s i z i n g t h e t e x t v i e w , t h i s c a n c a u s e t h e
// t e x t i n t h e t e x t v i e w t o b e " t o o h i g h " i n t h e t e x t v i e w .
// S o l u t i o n i s t o d i s a b l e a n i m a t i o n f o r s e t t i n g c o n t e n t o f f s e t .
override func setContentOffset ( _ contentOffset : CGPoint , animated : Bool ) {
super . setContentOffset ( contentOffset , animated : false )
}
}
override var intrinsicContentSize : CGSize {
get {
// S i n c e w e h a v e ` s e l f . a u t o r e s i z i n g M a s k = U I V i e w A u t o r e s i z i n g F l e x i b l e H e i g h t ` , w e m u s t s p e c i f y
// a n i n t r i n s i c C o n t e n t S i z e . S p e c i f y i n g C G S i z e . z e r o c a u s e s t h e h e i g h t t o b e d e t e r m i n e d b y a u t o l a y o u t .
return CGSize . zero
}
}
// MARK: - I n i t i a l i z e r s
init ( isAddMoreVisible : Bool ) {
self . addMoreButton = UIButton ( type : . custom )
self . sendButton = UIButton ( type : . system )
self . textView = MessageTextView ( )
self . textViewHeight = kMinTextViewHeight
super . init ( frame : CGRect . zero )
@ -1601,18 +1565,6 @@ class MediaMessageTextToolbar: UIView, UITextViewDelegate {
self . backgroundColor = UIColor . clear
textView . delegate = self
textView . keyboardAppearance = Theme . keyboardAppearance
textView . backgroundColor = Theme . darkThemeBackgroundColor
textView . tintColor = Theme . darkThemePrimaryColor
textView . layer . borderColor = Theme . darkThemePrimaryColor . cgColor
textView . layer . borderWidth = 0.5
textView . layer . cornerRadius = kMinTextViewHeight / 2
textView . font = UIFont . ows_dynamicTypeBody
textView . textColor = Theme . darkThemePrimaryColor
textView . returnKeyType = . done
textView . textContainerInset = UIEdgeInsets ( top : 7 , left : 7 , bottom : 7 , right : 7 )
textView . scrollIndicatorInsets = UIEdgeInsets ( top : 5 , left : 0 , bottom : 5 , right : 3 )
let addMoreIcon = # imageLiteral ( resourceName : " album_add_more " ) . withRenderingMode ( . alwaysTemplate )
addMoreButton . setImage ( addMoreIcon , for : . normal )
@ -1632,7 +1584,7 @@ class MediaMessageTextToolbar: UIView, UITextViewDelegate {
let contentView = UIView ( )
contentView . addSubview ( sendButton )
contentView . addSubview ( text View )
contentView . addSubview ( text Container )
contentView . addSubview ( lengthLimitLabel )
if isAddMoreVisible {
contentView . addSubview ( addMoreButton )
@ -1658,20 +1610,20 @@ class MediaMessageTextToolbar: UIView, UITextViewDelegate {
// S o i t d o e s n ' t w o r k a s e x p e c t e d w i t h R T L l a y o u t s w h e n w e e x p l i c i t l y w a n t s o m e t h i n g
// t o b e o n t h e r i g h t s i d e f o r b o t h R T L a n d L T R l a y o u t s , l i k e w i t h t h e s e n d b u t t o n .
// I b e l i e v e t h i s i s a b u g i n P u r e L a y o u t . F i l e d h e r e : h t t p s : / / g i t h u b . c o m / P u r e L a y o u t / P u r e L a y o u t / i s s u e s / 2 0 9
text View . autoPinEdge ( toSuperviewMargin : . top )
text View . autoPinEdge ( toSuperviewMargin : . bottom )
text Container . autoPinEdge ( toSuperviewMargin : . top )
text Container . autoPinEdge ( toSuperviewMargin : . bottom )
if isAddMoreVisible {
addMoreButton . autoPinEdge ( toSuperviewMargin : . left )
text View . autoPinEdge ( . left , to : . right , of : addMoreButton , withOffset : kToolbarMargin )
text Container . autoPinEdge ( . left , to : . right , of : addMoreButton , withOffset : kToolbarMargin )
addMoreButton . autoAlignAxis ( . horizontal , toSameAxisOf : sendButton )
addMoreButton . setContentHuggingHigh ( )
addMoreButton . setCompressionResistanceHigh ( )
} else {
text View . autoPinEdge ( toSuperviewMargin : . left )
text Container . autoPinEdge ( toSuperviewMargin : . left )
}
sendButton . autoPinEdge ( . left , to : . right , of : text View , withOffset : kToolbarMargin )
sendButton . autoPinEdge ( . bottom , to : . bottom , of : text View , withOffset : - 3 )
sendButton . autoPinEdge ( . left , to : . right , of : text Container , withOffset : kToolbarMargin )
sendButton . autoPinEdge ( . bottom , to : . bottom , of : text Container , withOffset : - 3 )
sendButton . autoPinEdge ( toSuperviewMargin : . right )
sendButton . setContentHuggingHigh ( )
@ -1679,7 +1631,7 @@ class MediaMessageTextToolbar: UIView, UITextViewDelegate {
lengthLimitLabel . autoPinEdge ( toSuperviewMargin : . left )
lengthLimitLabel . autoPinEdge ( toSuperviewMargin : . right )
lengthLimitLabel . autoPinEdge ( . bottom , to : . top , of : text View , withOffset : - 6 )
lengthLimitLabel . autoPinEdge ( . bottom , to : . top , of : text Container , withOffset : - 6 )
lengthLimitLabel . setContentHuggingHigh ( )
lengthLimitLabel . setCompressionResistanceHigh ( )
}
@ -1688,7 +1640,98 @@ class MediaMessageTextToolbar: UIView, UITextViewDelegate {
notImplemented ( )
}
// MARK: -
// MARK: - U I V i e w O v e r r i d e s
override var intrinsicContentSize : CGSize {
get {
// S i n c e w e h a v e ` s e l f . a u t o r e s i z i n g M a s k = U I V i e w A u t o r e s i z i n g F l e x i b l e H e i g h t ` , w e m u s t s p e c i f y
// a n i n t r i n s i c C o n t e n t S i z e . S p e c i f y i n g C G S i z e . z e r o c a u s e s t h e h e i g h t t o b e d e t e r m i n e d b y a u t o l a y o u t .
return CGSize . zero
}
}
// MARK: - S u b v i e w s
private let addMoreButton : UIButton
private let sendButton : UIButton
private lazy var lengthLimitLabel : UILabel = {
let lengthLimitLabel = UILabel ( )
// 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_MESSAGE_LENGTH_LIMIT_REACHED " , comment : " One-line label indicating the user can add no more text to the media message field. " )
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
lengthLimitLabel . isHidden = true
return lengthLimitLabel
} ( )
lazy var textView : UITextView = {
let textView = buildTextView ( )
textView . returnKeyType = . done
textView . scrollIndicatorInsets = UIEdgeInsets ( top : 5 , left : 0 , bottom : 5 , right : 3 )
return textView
} ( )
private lazy var placeholderTextView : UITextView = {
let placeholderTextView = buildTextView ( )
placeholderTextView . text = NSLocalizedString ( " MESSAGE_TEXT_FIELD_PLACEHOLDER " , comment : " placeholder text for the editable message field " )
placeholderTextView . isEditable = false
return placeholderTextView
} ( )
private lazy var textContainer : UIView = {
let textContainer = UIView ( )
textContainer . layer . borderColor = Theme . darkThemePrimaryColor . cgColor
textContainer . layer . borderWidth = 0.5
textContainer . layer . cornerRadius = kMinTextViewHeight / 2
textContainer . clipsToBounds = true
textContainer . addSubview ( placeholderTextView )
placeholderTextView . autoPinEdgesToSuperviewEdges ( )
textContainer . addSubview ( textView )
textView . autoPinEdgesToSuperviewEdges ( )
return textContainer
} ( )
private func buildTextView ( ) -> UITextView {
let textView = MessageTextView ( )
textView . keyboardAppearance = Theme . darkThemeKeyboardAppearance
textView . backgroundColor = . clear
textView . tintColor = Theme . darkThemePrimaryColor
textView . font = UIFont . ows_dynamicTypeBody
textView . textColor = Theme . darkThemePrimaryColor
textView . textContainerInset = UIEdgeInsets ( top : 7 , left : 7 , bottom : 7 , right : 7 )
return textView
}
class MessageTextView : UITextView {
// W h e n c r e a t i n g n e w l i n e s , c o n t e n t O f f s e t i s a n i m a t e d , b u t b e c a u s e
// w e a r e s i m u l t a n e o u s l y r e s i z i n g t h e t e x t v i e w , t h i s c a n c a u s e t h e
// t e x t i n t h e t e x t v i e w t o b e " t o o h i g h " i n t h e t e x t v i e w .
// S o l u t i o n i s t o d i s a b l e a n i m a t i o n f o r s e t t i n g c o n t e n t o f f s e t .
override func setContentOffset ( _ contentOffset : CGPoint , animated : Bool ) {
super . setContentOffset ( contentOffset , animated : false )
}
}
// MARK: - A c t i o n s
@objc func didTapSend ( ) {
mediaMessageTextToolbarDelegate ? . mediaMessageTextToolbarDidTapSend ( self )
@ -1741,14 +1784,36 @@ class MediaMessageTextToolbar: UIView, UITextViewDelegate {
public func textViewDidBeginEditing ( _ textView : UITextView ) {
mediaMessageTextToolbarDelegate ? . mediaMessageTextToolbarDidBeginEditing ( self )
updatePlaceholderTextViewVisibility ( )
}
public func textViewDidEndEditing ( _ textView : UITextView ) {
mediaMessageTextToolbarDelegate ? . mediaMessageTextToolbarDidEndEditing ( self )
updatePlaceholderTextViewVisibility ( )
}
// MARK: - H e l p e r s
func updatePlaceholderTextViewVisibility ( ) {
let isHidden : Bool = {
guard ! self . textView . isFirstResponder else {
return true
}
guard let captionText = self . textView . text else {
return false
}
guard captionText . count > 0 else {
return false
}
return true
} ( )
placeholderTextView . isHidden = isHidden
}
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