Improve boost screen header overscroll

This commit is contained in:
Ilya Laktyushin
2024-05-07 00:30:22 +04:00
parent c8c5b55f82
commit daea898fbb
2 changed files with 33 additions and 6 deletions

View File

@@ -20,29 +20,40 @@ import TelegramUIPreferences
public final class PremiumGradientBackgroundComponent: Component { public final class PremiumGradientBackgroundComponent: Component {
public let colors: [UIColor] public let colors: [UIColor]
public let cornerRadius: CGFloat
public let topOverscroll: Bool
public init( public init(
colors: [UIColor] colors: [UIColor],
cornerRadius: CGFloat = 10.0,
topOverscroll: Bool = false
) { ) {
self.colors = colors self.colors = colors
self.cornerRadius = cornerRadius
self.topOverscroll = topOverscroll
} }
public static func ==(lhs: PremiumGradientBackgroundComponent, rhs: PremiumGradientBackgroundComponent) -> Bool { public static func ==(lhs: PremiumGradientBackgroundComponent, rhs: PremiumGradientBackgroundComponent) -> Bool {
if lhs.colors != rhs.colors { if lhs.colors != rhs.colors {
return false return false
} }
if lhs.cornerRadius != rhs.cornerRadius {
return false
}
if lhs.topOverscroll != rhs.topOverscroll {
return false
}
return true return true
} }
public final class View: UIView { public final class View: UIView {
private let clipLayer: CALayer private let clipLayer: CAReplicatorLayer
private let gradientLayer: CAGradientLayer private let gradientLayer: CAGradientLayer
private var component: PremiumGradientBackgroundComponent? private var component: PremiumGradientBackgroundComponent?
override init(frame: CGRect) { override init(frame: CGRect) {
self.clipLayer = CALayer() self.clipLayer = CAReplicatorLayer()
self.clipLayer.cornerRadius = 10.0
self.clipLayer.masksToBounds = true self.clipLayer.masksToBounds = true
self.gradientLayer = CAGradientLayer() self.gradientLayer = CAGradientLayer()
@@ -61,22 +72,36 @@ public final class PremiumGradientBackgroundComponent: Component {
func update(component: PremiumGradientBackgroundComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize { func update(component: PremiumGradientBackgroundComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
self.clipLayer.frame = CGRect(origin: .zero, size: CGSize(width: availableSize.width, height: availableSize.height + 10.0)) self.clipLayer.frame = CGRect(origin: .zero, size: CGSize(width: availableSize.width, height: availableSize.height + 10.0))
self.gradientLayer.frame = CGRect(origin: .zero, size: availableSize) self.gradientLayer.frame = CGRect(origin: .zero, size: availableSize)
var locations: [NSNumber] = [] var locations: [NSNumber] = []
let delta = 1.0 / CGFloat(component.colors.count - 1) let delta = 1.0 / CGFloat(component.colors.count - 1)
for i in 0 ..< component.colors.count { for i in 0 ..< component.colors.count {
locations.append((delta * CGFloat(i)) as NSNumber) locations.append((delta * CGFloat(i)) as NSNumber)
} }
self.gradientLayer.locations = locations self.gradientLayer.locations = locations
self.gradientLayer.colors = component.colors.reversed().map { $0.cgColor } self.gradientLayer.colors = component.colors.reversed().map { $0.cgColor }
self.gradientLayer.type = .radial self.gradientLayer.type = .radial
self.gradientLayer.startPoint = CGPoint(x: 1.0, y: 0.0) self.gradientLayer.startPoint = CGPoint(x: 1.0, y: 0.0)
self.gradientLayer.endPoint = CGPoint(x: -2.0, y: 3.0) self.gradientLayer.endPoint = CGPoint(x: -2.0, y: 3.0)
self.clipLayer.cornerRadius = component.cornerRadius
self.component = component self.component = component
self.setupGradientAnimations() self.setupGradientAnimations()
if component.topOverscroll {
self.clipLayer.instanceCount = 2
var instanceTransform = CATransform3DIdentity
instanceTransform = CATransform3DTranslate(instanceTransform, 0.0, -availableSize.height * 1.5, 0.0)
instanceTransform = CATransform3DScale(instanceTransform, 1.0, -2.0, 1.0)
self.clipLayer.instanceTransform = instanceTransform
self.clipLayer.masksToBounds = false
} else {
self.clipLayer.masksToBounds = true
}
return availableSize return availableSize
} }

View File

@@ -308,7 +308,9 @@ private final class BoostHeaderComponent: CombinedComponent {
UIColor(rgb: 0x6b93ff), UIColor(rgb: 0x6b93ff),
UIColor(rgb: 0x8878ff), UIColor(rgb: 0x8878ff),
UIColor(rgb: 0xe46ace) UIColor(rgb: 0xe46ace)
] ],
cornerRadius: 0.0,
topOverscroll: true
), ),
availableSize: size, availableSize: size,
transition: context.transition transition: context.transition