Various improvements

This commit is contained in:
Isaac 2026-01-31 00:37:35 +08:00
parent 37ffcf76e9
commit ad731bf237
5 changed files with 107 additions and 30 deletions

View file

@ -114,12 +114,14 @@ public extension ComponentTransition {
options.insert(.allowUserInteraction)
}
switch curve {
case .spring, .bounce:
case .spring, .bounce, .custom:
var parameters: CALayerSpringParametersOverrideParameters?
var dampingValue: CGFloat = 500.0
if case let .bounce(stiffness, damping) = curve {
dampingValue = damping
parameters = CALayerSpringParametersOverrideParameters(stiffness: stiffness, damping: damping, duration: duration)
parameters = CALayerSpringParametersOverrideParametersSpring(stiffness: stiffness, damping: damping, duration: duration)
} else if case let .custom(a, b, c, d) = curve {
parameters = CALayerSpringParametersOverrideParametersCustomCurve(cp1: CGPoint(x: CGFloat(a), y: CGFloat(b)), cp2: CGPoint(x: CGFloat(c), y: CGFloat(d)))
}
CALayer.push(CALayerSpringParametersOverride(parameters: parameters))
UIView.animate(withDuration: duration, delay: delay, usingSpringWithDamping: dampingValue, initialSpringVelocity: 0.0, options: options, animations: {

View file

@ -45,7 +45,9 @@ public final class ChatNavigationBarTitleView: UIView, NavigationBarTitleView {
private var activities: ChatTitleComponent.Activities?
private var networkState: AccountNetworkState?
private var ignoreParentTransitionRequests: Bool = false
public var requestUpdate: ((ContainedViewLayoutTransition) -> Void)?
public var tapAction: (() -> Void)?
public var longTapAction: (() -> Void)?
@ -82,8 +84,10 @@ public final class ChatNavigationBarTitleView: UIView, NavigationBarTitleView {
dateTimeFormat: PresentationDateTimeFormat,
nameDisplayOrder: PresentationPersonNameOrder,
content: ChatTitleContent,
transition: ComponentTransition
transition: ComponentTransition,
ignoreParentTransitionRequests: Bool = false
) {
self.ignoreParentTransitionRequests = ignoreParentTransitionRequests
self.contentData = ContentData(
context: context,
theme: theme,
@ -95,6 +99,7 @@ public final class ChatNavigationBarTitleView: UIView, NavigationBarTitleView {
content: content
)
self.update(transition: transition)
self.ignoreParentTransitionRequests = false
}
public func updateActivities(activities: ChatTitleComponent.Activities?, transition: ComponentTransition) {
@ -112,7 +117,9 @@ public final class ChatNavigationBarTitleView: UIView, NavigationBarTitleView {
}
private func update(transition: ComponentTransition) {
self.requestUpdate?(transition.containedViewLayoutTransition)
if !self.ignoreParentTransitionRequests {
self.requestUpdate?(transition.containedViewLayoutTransition)
}
}
public func updateLayout(availableSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {

View file

@ -456,6 +456,25 @@ func updateChatPresentationInterfaceStateImpl(
selfController.tempHideAccessoryPanels = selfController.presentationInterfaceState.search != nil
if let chatTitleContent = selfController.contentData?.state.chatTitleContent {
var titleTransition = ComponentTransition(transition)
if case .messageOptions = selfController.subject {
titleTransition = titleTransition.withAnimation(.none)
}
selfController.chatTitleView?.update(
context: selfController.context,
theme: selfController.presentationData.theme,
preferClearGlass: selfController.presentationInterfaceState.preferredGlassType == .clear,
wallpaper: selfController.presentationInterfaceState.chatWallpaper,
strings: selfController.presentationData.strings,
dateTimeFormat: selfController.presentationData.dateTimeFormat,
nameDisplayOrder: selfController.presentationData.nameDisplayOrder,
content: chatTitleContent,
transition: titleTransition,
ignoreParentTransitionRequests: true
)
}
if selfController.isNodeLoaded {
selfController.chatDisplayNode.updateChatPresentationInterfaceState(updatedChatPresentationInterfaceState, transition: transition, interactive: interactive, completion: completion)
} else {
@ -609,23 +628,5 @@ func updateChatPresentationInterfaceStateImpl(
}
}
if let chatTitleContent = selfController.contentData?.state.chatTitleContent {
var titleTransition = ComponentTransition(transition)
if case .messageOptions = selfController.subject {
titleTransition = titleTransition.withAnimation(.none)
}
selfController.chatTitleView?.update(
context: selfController.context,
theme: selfController.presentationData.theme,
preferClearGlass: selfController.presentationInterfaceState.preferredGlassType == .clear,
wallpaper: selfController.presentationInterfaceState.chatWallpaper,
strings: selfController.presentationData.strings,
dateTimeFormat: selfController.presentationData.dateTimeFormat,
nameDisplayOrder: selfController.presentationData.nameDisplayOrder,
content: chatTitleContent,
transition: titleTransition
)
}
selfController.stateUpdated?(transition)
}

View file

@ -28,6 +28,12 @@ typedef NS_OPTIONS(NSUInteger, UIResponderDisableAutomaticKeyboardHandling) {
@interface CALayerSpringParametersOverrideParameters : NSObject
- (instancetype _Nonnull)init;
@end
@interface CALayerSpringParametersOverrideParametersSpring : CALayerSpringParametersOverrideParameters
@property (nonatomic, readonly) CGFloat stiffness;
@property (nonatomic, readonly) CGFloat damping;
@property (nonatomic, readonly) double duration;
@ -36,6 +42,15 @@ typedef NS_OPTIONS(NSUInteger, UIResponderDisableAutomaticKeyboardHandling) {
@end
@interface CALayerSpringParametersOverrideParametersCustomCurve : CALayerSpringParametersOverrideParameters
@property (nonatomic, readonly) CGPoint cp1;
@property (nonatomic, readonly) CGPoint cp2;
- (instancetype _Nonnull)initWithCp1:(CGPoint)cp1 cp2:(CGPoint)cp2;
@end
@interface CALayerSpringParametersOverride : NSObject
@property (nonatomic, strong, readonly) CALayerSpringParametersOverrideParameters * _Nullable parameters;

View file

@ -115,18 +115,42 @@ static bool notyfyingShiftState = false;
@implementation CALayerSpringParametersOverrideParameters
- (instancetype _Nonnull)initWithStiffness:(CGFloat)stiffness damping:(CGFloat)damping duration:(double)duration; {
- (instancetype _Nonnull)init {
self = [super init];
if (self != nil) {
_stiffness = stiffness;
_damping = damping;
_duration = duration;
}
return self;
}
@end
@implementation CALayerSpringParametersOverrideParametersSpring
- (instancetype _Nonnull)initWithStiffness:(CGFloat)stiffness damping:(CGFloat)damping duration:(double)duration {
self = [super init];
if (self != nil) {
_stiffness = stiffness;
_damping = damping;
}
return self;
}
@end
@implementation CALayerSpringParametersOverrideParametersCustomCurve
- (instancetype _Nonnull)initWithCp1:(CGPoint)cp1 cp2:(CGPoint)cp2 {
self = [super init];
if (self != nil) {
_cp1 = cp1;
_cp2 = cp2;
}
return self;
}
@end
@implementation CALayerSpringParametersOverride
- (instancetype _Nonnull)initWithParameters:(CALayerSpringParametersOverrideParameters * _Nullable)parameters {
@ -167,12 +191,13 @@ static NSMutableArray<CALayerSpringParametersOverride *> *currentSpringParameter
if (currentSpringParametersOverrideStack().count != 0 && [anim isKindOfClass:[CASpringAnimation class]]) {
CALayerSpringParametersOverride *overrideData = [currentSpringParametersOverrideStack() lastObject];
if (overrideData) {
if (overrideData.parameters) {
if ([overrideData.parameters isKindOfClass:[CALayerSpringParametersOverrideParametersSpring class]]) {
CALayerSpringParametersOverrideParametersSpring *parameters = (CALayerSpringParametersOverrideParametersSpring *)overrideData.parameters;
CABasicAnimation *sourceAnimation = (CABasicAnimation *)anim;
CASpringAnimation *animation = makeSpringBounceAnimationImpl(sourceAnimation.keyPath, 0.0, overrideData.parameters.damping);
CASpringAnimation *animation = makeSpringBounceAnimationImpl(sourceAnimation.keyPath, 0.0, parameters.damping);
animation.stiffness = overrideData.parameters.stiffness;
animation.stiffness = parameters.stiffness;
animation.fromValue = sourceAnimation.fromValue;
animation.toValue = sourceAnimation.toValue;
animation.byValue = sourceAnimation.byValue;
@ -189,7 +214,34 @@ static NSMutableArray<CALayerSpringParametersOverride *> *currentSpringParameter
if (k != 0.0 && k != 1.0) {
speed = 1.0f / k;
}
animation.speed = sourceAnimation.speed * (float)(animation.duration / overrideData.parameters.duration);
animation.speed = sourceAnimation.speed * (float)(animation.duration / parameters.duration);
updatedAnimation = animation;
} else if ([overrideData.parameters isKindOfClass:[CALayerSpringParametersOverrideParametersCustomCurve class]]) {
CALayerSpringParametersOverrideParametersCustomCurve *parameters = (CALayerSpringParametersOverrideParametersCustomCurve *)overrideData.parameters;
CABasicAnimation *sourceAnimation = (CABasicAnimation *)anim;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:sourceAnimation.keyPath];
animation.fromValue = sourceAnimation.fromValue;
animation.toValue = sourceAnimation.toValue;
animation.byValue = sourceAnimation.byValue;
animation.additive = sourceAnimation.additive;
animation.duration = sourceAnimation.duration;
animation.timingFunction = [[CAMediaTimingFunction alloc] initWithControlPoints:parameters.cp1.x :parameters.cp1.y :parameters.cp2.x :parameters.cp2.y];
animation.removedOnCompletion = sourceAnimation.isRemovedOnCompletion;
animation.fillMode = sourceAnimation.fillMode;
animation.speed = sourceAnimation.speed;
animation.beginTime = sourceAnimation.beginTime;
animation.timeOffset = sourceAnimation.timeOffset;
animation.repeatCount = sourceAnimation.repeatCount;
animation.autoreverses = sourceAnimation.autoreverses;
float k = animationDurationFactorImpl();
float speed = 1.0f;
if (k != 0.0 && k != 1.0) {
speed = 1.0f / k;
}
animation.speed = speed * sourceAnimation.speed;
updatedAnimation = animation;
} else {