@@ -3,6 +3,7 @@ import UIKit
33import Display
44import AsyncDisplayKit
55import TelegramPresentationData
6+ import ComponentFlow
67
78public struct CounterControllerTitle : Equatable {
89 public var title : String
@@ -16,24 +17,28 @@ public struct CounterControllerTitle: Equatable {
1617
1718public final class CounterControllerTitleView : UIView {
1819 private let titleNode : ImmediateTextNode
19- private let subtitleNode : ImmediateTextNode
20+
21+ private var subtitleNode : ImmediateTextNode
22+ private var disappearingSubtitleNode : ImmediateTextNode ?
2023
2124 public var title : CounterControllerTitle = CounterControllerTitle ( title: " " , counter: nil ) {
2225 didSet {
2326 if self . title != oldValue {
24- self . update ( )
27+ self . update ( animated : oldValue . title . isEmpty == self . title . title . isEmpty )
2528 }
2629 }
2730 }
2831
2932 public var theme : PresentationTheme {
3033 didSet {
31- self . update ( )
34+ self . update ( animated : false )
3235 }
3336 }
3437
3538 private var primaryTextColor : UIColor ?
3639 private var secondaryTextColor : UIColor ?
40+
41+ private var nextLayoutTransition : ContainedViewLayoutTransition ?
3742
3843 public func updateTextColors( primary: UIColor ? , secondary: UIColor ? , transition: ContainedViewLayoutTransition ) {
3944 self . primaryTextColor = primary
@@ -52,18 +57,40 @@ public final class CounterControllerTitleView: UIView {
5257 }
5358 }
5459
55- self . update ( )
60+ self . update ( animated : false )
5661 }
5762
58- private func update( ) {
63+ private func update( animated : Bool ) {
5964 let primaryTextColor = self . primaryTextColor ?? self . theme. rootController. navigationBar. primaryTextColor
6065 let secondaryTextColor = self . secondaryTextColor ?? self . theme. rootController. navigationBar. secondaryTextColor
6166 self . titleNode. attributedText = NSAttributedString ( string: self . title. title, font: Font . semibold ( 17.0 ) , textColor: primaryTextColor)
62- self . subtitleNode. attributedText = NSAttributedString ( string: self . title. counter ?? " " , font: Font . with ( size: 13.0 , traits: . monospacedNumbers) , textColor: secondaryTextColor)
67+
68+ let subtitleText = NSAttributedString ( string: self . title. counter ?? " " , font: Font . with ( size: 13.0 , traits: . monospacedNumbers) , textColor: secondaryTextColor)
69+ if let previousSubtitleText = self . subtitleNode. attributedText, previousSubtitleText. string. isEmpty != subtitleText. string. isEmpty && subtitleText. string. isEmpty {
70+ if let disappearingSubtitleNode = self . disappearingSubtitleNode {
71+ self . disappearingSubtitleNode = nil
72+ disappearingSubtitleNode. removeFromSupernode ( )
73+ }
74+
75+ self . disappearingSubtitleNode = self . subtitleNode
76+
77+ self . subtitleNode = ImmediateTextNode ( )
78+ self . subtitleNode. displaysAsynchronously = false
79+ self . subtitleNode. maximumNumberOfLines = 1
80+ self . subtitleNode. truncationType = . end
81+ self . subtitleNode. isOpaque = false
82+ self . subtitleNode. attributedText = subtitleText
83+ self . addSubnode ( self . subtitleNode)
84+ } else {
85+ self . subtitleNode. attributedText = subtitleText
86+ }
6387
6488 self . accessibilityLabel = self . title. title
6589 self . accessibilityValue = self . title. counter
6690
91+ if animated {
92+ self . nextLayoutTransition = . animated( duration: 0.4 , curve: . spring)
93+ }
6794 self . setNeedsLayout ( )
6895 }
6996
@@ -110,11 +137,31 @@ public final class CounterControllerTitleView: UIView {
110137 } else {
111138 combinedHeight = titleSize. height
112139 }
140+
141+ var transition : ContainedViewLayoutTransition = . immediate
142+ if let nextLayoutTransition = self . nextLayoutTransition {
143+ if !self . titleNode. bounds. isEmpty {
144+ transition = nextLayoutTransition
145+ }
146+ self . nextLayoutTransition = nil
147+ }
113148
114149 let titleFrame = CGRect ( origin: CGPoint ( x: floor ( ( size. width - titleSize. width) / 2.0 ) , y: floor ( ( size. height - combinedHeight) / 2.0 ) ) , size: titleSize)
115- self . titleNode. frame = titleFrame
150+ self . titleNode. bounds = CGRect ( origin: CGPoint ( ) , size: titleFrame. size)
151+ transition. updatePosition ( node: self . titleNode, position: titleFrame. center)
116152
117153 let subtitleFrame = CGRect ( origin: CGPoint ( x: floor ( ( size. width - subtitleSize. width) / 2.0 ) , y: floor ( ( size. height - combinedHeight) / 2.0 ) + titleSize. height + spacing) , size: subtitleSize)
118- self . subtitleNode. frame = subtitleFrame
154+ self . subtitleNode. bounds = CGRect ( origin: CGPoint ( ) , size: subtitleFrame. size)
155+ transition. updatePosition ( node: self . subtitleNode, position: subtitleFrame. center)
156+ transition. updateTransformScale ( node: self . subtitleNode, scale: self . title. counter != nil ? 1.0 : 0.001 )
157+ transition. updateAlpha ( node: self . subtitleNode, alpha: self . title. counter != nil ? 1.0 : 0.0 )
158+
159+ if let disappearingSubtitleNode = self . disappearingSubtitleNode {
160+ transition. updatePosition ( node: disappearingSubtitleNode, position: subtitleFrame. center)
161+ transition. updateTransformScale ( node: disappearingSubtitleNode, scale: self . title. counter != nil ? 1.0 : 0.001 )
162+ transition. updateAlpha ( node: disappearingSubtitleNode, alpha: self . title. counter != nil ? 1.0 : 0.0 , completion: { [ weak disappearingSubtitleNode] _ in
163+ disappearingSubtitleNode? . removeFromSupernode ( )
164+ } )
165+ }
119166 }
120167}
0 commit comments