mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
136 lines
4.2 KiB
Swift
136 lines
4.2 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import Display
|
|
import AsyncDisplayKit
|
|
import LegacyComponents
|
|
|
|
private let transitionDuration = 0.2
|
|
private let animationKey = "animation"
|
|
|
|
public class ChatTitleActivityIndicatorNode: ASDisplayNode {
|
|
public var duration: CFTimeInterval {
|
|
return 0.0
|
|
}
|
|
|
|
public var timingFunction: CAMediaTimingFunction {
|
|
return CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
|
|
}
|
|
|
|
public var color: UIColor? {
|
|
didSet {
|
|
self.setNeedsDisplay()
|
|
}
|
|
}
|
|
|
|
public var progress: CGFloat = 0.0 {
|
|
didSet {
|
|
self.setNeedsDisplay()
|
|
}
|
|
}
|
|
|
|
public init(color: UIColor) {
|
|
self.color = color
|
|
|
|
super.init()
|
|
|
|
self.isLayerBacked = true
|
|
self.displaysAsynchronously = true
|
|
self.isOpaque = false
|
|
}
|
|
|
|
deinit {
|
|
self.stopAnimation()
|
|
}
|
|
|
|
private func startAnimation() {
|
|
self.stopAnimation()
|
|
|
|
let animation = POPBasicAnimation()
|
|
animation.property = POPAnimatableProperty.property(withName: "progress", initializer: { property in
|
|
property?.readBlock = { node, values in
|
|
values?.pointee = (node as! ChatTitleActivityIndicatorNode).progress
|
|
}
|
|
property?.writeBlock = { node, values in
|
|
(node as! ChatTitleActivityIndicatorNode).progress = values!.pointee
|
|
}
|
|
property?.threshold = 0.01
|
|
}) as? POPAnimatableProperty
|
|
animation.fromValue = 0.0 as NSNumber
|
|
animation.toValue = 1.0 as NSNumber
|
|
animation.timingFunction = self.timingFunction
|
|
animation.duration = self.duration
|
|
animation.repeatForever = true
|
|
|
|
self.pop_add(animation, forKey: animationKey)
|
|
}
|
|
|
|
private func stopAnimation() {
|
|
self.pop_removeAnimation(forKey: animationKey)
|
|
}
|
|
|
|
override public func didEnterHierarchy() {
|
|
super.didEnterHierarchy()
|
|
self.startAnimation()
|
|
}
|
|
|
|
override public func didExitHierarchy() {
|
|
super.didExitHierarchy()
|
|
self.stopAnimation()
|
|
}
|
|
}
|
|
|
|
public class ChatTitleActivityContentNode: ASDisplayNode {
|
|
public let textNode: ImmediateTextNode
|
|
|
|
public init(text: NSAttributedString) {
|
|
self.textNode = ImmediateTextNode()
|
|
self.textNode.displaysAsynchronously = false
|
|
self.textNode.maximumNumberOfLines = 1
|
|
self.textNode.isOpaque = false
|
|
|
|
super.init()
|
|
|
|
self.addSubnode(self.textNode)
|
|
|
|
self.textNode.attributedText = text
|
|
}
|
|
|
|
func makeCopy() -> ASDisplayNode {
|
|
let node = ASDisplayNode()
|
|
let textNode = self.textNode.makeCopy()
|
|
textNode.frame = self.textNode.frame
|
|
node.addSubnode(textNode)
|
|
node.frame = self.frame
|
|
return node
|
|
}
|
|
|
|
public func animateOut(to: ChatTitleActivityNodeState, style: ChatTitleActivityAnimationStyle, completion: @escaping () -> Void) {
|
|
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: transitionDuration, removeOnCompletion: false, completion: { _ in
|
|
completion()
|
|
})
|
|
|
|
if case .slide = style {
|
|
self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: 14.0), duration: transitionDuration, additive: true)
|
|
}
|
|
}
|
|
|
|
public func animateIn(from: ChatTitleActivityNodeState, style: ChatTitleActivityAnimationStyle) {
|
|
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: transitionDuration)
|
|
|
|
if case .slide = style {
|
|
self.layer.animatePosition(from: CGPoint(x: 0.0, y: -14.0), to: CGPoint(), duration: transitionDuration, additive: true)
|
|
}
|
|
}
|
|
|
|
public func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
|
let size = self.textNode.updateLayout(constrainedSize)
|
|
self.textNode.bounds = CGRect(origin: CGPoint(), size: size)
|
|
if case .center = alignment {
|
|
self.textNode.position = CGPoint(x: 0.0, y: size.height / 2.0)
|
|
} else {
|
|
self.textNode.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
|
}
|
|
return size
|
|
}
|
|
}
|