mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
90 lines
3.9 KiB
Swift
90 lines
3.9 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import AsyncDisplayKit
|
|
import Display
|
|
|
|
enum PasscodeEntryTitleAnimation {
|
|
case none
|
|
case slideIn
|
|
case crossFade
|
|
}
|
|
|
|
final class PasscodeEntryLabelNode: ASDisplayNode {
|
|
private let wrapperNode: ASDisplayNode
|
|
private let textNode: ASTextNode
|
|
|
|
private var validLayout: ContainerViewLayout?
|
|
|
|
override init() {
|
|
self.wrapperNode = ASDisplayNode()
|
|
self.wrapperNode.clipsToBounds = true
|
|
|
|
self.textNode = ASTextNode()
|
|
self.textNode.isLayerBacked = false
|
|
|
|
super.init()
|
|
|
|
self.addSubnode(self.wrapperNode)
|
|
self.wrapperNode.addSubnode(self.textNode)
|
|
}
|
|
|
|
func setAttributedText(_ text: NSAttributedString, animation: PasscodeEntryTitleAnimation = .none, completion: @escaping () -> Void = {}) {
|
|
switch animation {
|
|
case .none:
|
|
self.textNode.attributedText = text
|
|
completion()
|
|
|
|
if let validLayout = self.validLayout {
|
|
let _ = self.updateLayout(layout: validLayout, transition: .immediate)
|
|
}
|
|
case .slideIn:
|
|
self.textNode.attributedText = text
|
|
if let validLayout = self.validLayout {
|
|
let _ = self.updateLayout(layout: validLayout, transition: .immediate)
|
|
}
|
|
|
|
let offset = self.wrapperNode.bounds.width / 2.0
|
|
self.wrapperNode.layer.animatePosition(from: CGPoint(x: -offset, y: 0.0), to: CGPoint(), duration: 0.45, additive: true)
|
|
self.textNode.layer.animatePosition(from: CGPoint(x: offset * 2.0, y: 0.0), to: CGPoint(), duration: 0.45, additive: true, completion: { _ in
|
|
completion()
|
|
})
|
|
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
|
case .crossFade:
|
|
if let snapshotView = self.textNode.view.snapshotContentTree() {
|
|
snapshotView.frame = self.textNode.frame
|
|
self.textNode.view.superview?.insertSubview(snapshotView, aboveSubview: self.textNode.view)
|
|
self.textNode.alpha = 0.0
|
|
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
|
snapshotView?.removeFromSuperview()
|
|
self.textNode.attributedText = text
|
|
self.textNode.alpha = 1.0
|
|
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, completion: { _ in
|
|
completion()
|
|
})
|
|
if let validLayout = self.validLayout {
|
|
let _ = self.updateLayout(layout: validLayout, transition: .immediate)
|
|
}
|
|
})
|
|
} else {
|
|
self.textNode.attributedText = text
|
|
self.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
|
|
completion()
|
|
if let validLayout = self.validLayout {
|
|
let _ = self.updateLayout(layout: validLayout, transition: .immediate)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func updateLayout(layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) -> CGSize {
|
|
self.validLayout = layout
|
|
|
|
let textSize = self.textNode.measure(layout.size)
|
|
let textFrame = CGRect(x: floor((layout.size.width - textSize.width) / 2.0), y: 0.0, width: textSize.width, height: textSize.height)
|
|
transition.updateFrame(node: self.wrapperNode, frame: textFrame)
|
|
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(), size: textSize))
|
|
|
|
return CGSize(width: layout.size.width, height: 25.0)
|
|
}
|
|
}
|