@ -17,7 +17,6 @@ final class ReactionContainerView: UIView {
private static let maxEmojiBeforeCollapse : Int = 6
private var maxWidth : CGFloat = 0
private var collapsedCount : Int = 0
private var showingAllReactions : Bool = false
private var showNumbers : Bool = true
private var oldSize : CGSize = . zero
@ -27,8 +26,6 @@ final class ReactionContainerView: UIView {
// MARK: - U I
private var collapseTextLabelRightConstraint : NSLayoutConstraint ?
private let dummyReactionButton : ReactionButton = ReactionButton (
viewModel : ReactionViewModel (
emoji : EmojiWithSkinTones ( baseEmoji : . a , skinTones : nil ) ,
@ -64,6 +61,7 @@ final class ReactionContainerView: UIView {
. withRenderingMode ( . alwaysTemplate )
)
arrow . themeTintColor = . textPrimary
arrow . setContentHuggingPriority ( . required , for : . horizontal )
let textLabel : UILabel = UILabel ( )
textLabel . setContentHuggingPriority ( . required , for : . vertical )
@ -80,12 +78,11 @@ final class ReactionContainerView: UIView {
result . addSubview ( textLabel )
arrow . pin ( . top , to : . top , of : result )
arrow . pin ( . leading , to : . leading , of : result )
arrow . pin ( . bottom , to : . bottom , of : result )
textLabel . center ( . horizontal , in : result , withInset : ( ReactionContainerView . arrowSize . width / 2 ) )
textLabel . pin ( . top , to : . top , of : result )
textLabel . pin ( . leading , to : . trailing , of : arrow , withInset : ReactionContainerView . arrowSpacing )
collapseTextLabelRightConstraint = textLabel . pin ( . trailing , to : . trailing , of : result )
textLabel . pin ( . bottom , to : . bottom , of : result )
return result
@ -114,37 +111,7 @@ final class ReactionContainerView: UIView {
mainStackView . pin ( . trailing , to : . trailing , of : self )
mainStackView . pin ( . bottom , to : . bottom , of : self , withInset : - Values . verySmallSpacing )
reactionContainerView . set ( . width , to : . width , of : mainStackView )
}
override func layoutSubviews ( ) {
super . layoutSubviews ( )
// N o t e : W e u p d a t e t h e ' c o l l a p s e T e x t L a b e l R i g h t C o n s t r a i n t ' t o t r y t o m a k e t h e " s h o w l e s s "
// b u t t o n a p p e a r h o r i z o n t a l l y c e n t e r e d ( i f w e d o n ' t d o t h i s i t g e t s o f f s e t t o o n e s i d e )
guard frame != CGRect . zero , frame . size != oldSize else { return }
let targetSuperview : UIView ? = {
var result : UIView ? = self . superview
while result != nil , result ? . isKind ( of : UITableViewCell . self ) != true {
result = result ? . superview
}
return result
} ( )
if let targetSuperview : UIView = targetSuperview {
let parentWidth : CGFloat = targetSuperview . bounds . width
let frameInParent : CGRect = targetSuperview . convert ( self . bounds , from : self )
let centeredWidth : CGFloat = ( parentWidth - ( frameInParent . minX * 2 ) )
let diff : CGFloat = ( frameInParent . width - centeredWidth )
collapseTextLabelRightConstraint ? . constant = - (
diff +
( ( ReactionContainerView . arrowSize . width + ReactionContainerView . arrowSpacing ) / 2 )
)
}
oldSize = frame . size
collapseButton . set ( . width , to : . width , of : mainStackView )
}
public func update (
@ -155,7 +122,17 @@ final class ReactionContainerView: UIView {
) {
self . reactions = reactions
self . maxWidth = maxWidth
self . collapsedCount = {
self . showNumbers = showNumbers
self . reactionViews = [ ]
self . reactionContainerView . arrangedSubviews . forEach { $0 . removeFromSuperview ( ) }
let collapsedCount : Int = {
// I f t h e r e a r e a l r e a d y m o r e t h a n ' m a x E m o j i B e f o r e C o l l a p s e ' t h e n n o n e e d t o c a l c u l a t e , j u s t
// a l w a y s c o l l a p s e
guard reactions . count <= ReactionContainerView . maxEmojiBeforeCollapse else {
return ReactionContainerView . numCollapsedEmoji
}
var numReactions : Int = 0
var runningWidth : CGFloat = 0
let estimatedExpandingButtonWidth : CGFloat = 52
@ -180,27 +157,21 @@ final class ReactionContainerView: UIView {
numReactions += 1
}
return ( numReactions > ReactionContainerView . maxEmojiBeforeCollapse ?
ReactionContainerView . numCollapsedEmoji :
numReactions
)
return numReactions
} ( )
self . showNumbers = showNumbers
self . reactionViews = [ ]
self . reactionContainerView . arrangedSubviews . forEach { $0 . removeFromSuperview ( ) }
// G e n e r a t e t h e l i n e s o f r e a c t i o n s ( i f t h e ' c o l l a p s e d C o u n t ' m a t c h e s t h e t o t a l n u m b e r o f
// r e a c t i o n s t h e n j u s t s h o w t h e m a p p )
if showingAllReactions || self . collapsedCount >= reactions . count {
if showingAllReactions || collapsedCount >= reactions . count {
self . updateAllReactions ( reactions , maxWidth : maxWidth , showNumbers : showNumbers )
}
else {
self . updateCollapsedReactions ( reactions , maxWidth : maxWidth , showNumbers : showNumbers )
self . updateCollapsedReactions ( reactions , maxWidth : maxWidth , showNumbers : showNumbers , collapsedCount : collapsedCount )
}
// J u s t i n c a s e w e c o u l d n ' t s h o w e v e r y t h i n g f o r s o m e r e a s o n u p d a t e t h i s b a s e d o n t h e
// i n t e r n a l l o g i c
self . collapseButton . isHidden = ( self . reactionContainerView . arrangedSubviews . count <= 1 )
self . collapseButton . isHidden = ! showingAllReactions
self . showingAllReactions = ! self . collapseButton . isHidden
self . layoutIfNeeded ( )
}
@ -218,15 +189,16 @@ final class ReactionContainerView: UIView {
private func updateCollapsedReactions (
_ reactions : [ ReactionViewModel ] ,
maxWidth : CGFloat ,
showNumbers : Bool
showNumbers : Bool ,
collapsedCount : Int
) {
guard ! reactions . isEmpty else { return }
let maxSize : CGSize = CGSize ( width : maxWidth , height : 9999 )
let stackView : UIStackView = createLineStackView ( )
let displayedReactions : [ ReactionViewModel ] = Array ( reactions . prefix ( upTo : self . collapsedCount ) )
let displayedReactions : [ ReactionViewModel ] = Array ( reactions . prefix ( upTo : collapsedCount ) )
let expandButtonReactions : [ EmojiWithSkinTones ] = reactions
. suffix ( from : self . collapsedCount )
. suffix ( from : collapsedCount )
. prefix ( 3 )
. map { $0 . emoji }