mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-28 02:45:58 +00:00
Update
This commit is contained in:
parent
7ed1261193
commit
c32d05fdb2
@ -830,7 +830,7 @@ public extension ContainedViewLayoutTransition {
|
||||
}
|
||||
|
||||
func updateAlpha(node: ASDisplayNode, alpha: CGFloat, beginWithCurrentState: Bool = false, force: Bool = false, delay: Double = 0.0, completion: ((Bool) -> Void)? = nil) {
|
||||
if node.alpha.isEqual(to: alpha) && !force {
|
||||
if node.layer.opacity == Float(alpha) && !force {
|
||||
if let completion = completion {
|
||||
completion(true)
|
||||
}
|
||||
@ -844,14 +844,18 @@ public extension ContainedViewLayoutTransition {
|
||||
completion(true)
|
||||
}
|
||||
case let .animated(duration, curve):
|
||||
let previousAlpha: CGFloat
|
||||
let previousAlpha: Float
|
||||
if beginWithCurrentState, let presentation = node.layer.presentation() {
|
||||
previousAlpha = CGFloat(presentation.opacity)
|
||||
previousAlpha = presentation.opacity
|
||||
} else {
|
||||
previousAlpha = node.alpha
|
||||
previousAlpha = node.layer.opacity
|
||||
}
|
||||
if alpha == 0.0 {
|
||||
node.layer.opacity = Float(alpha)
|
||||
} else {
|
||||
node.alpha = alpha
|
||||
node.layer.animateAlpha(from: previousAlpha, to: alpha, duration: duration, delay: delay, timingFunction: curve.timingFunction, mediaTimingFunction: curve.mediaTimingFunction, completion: { result in
|
||||
}
|
||||
node.layer.animateAlpha(from: CGFloat(previousAlpha), to: alpha, duration: duration, delay: delay, timingFunction: curve.timingFunction, mediaTimingFunction: curve.mediaTimingFunction, completion: { result in
|
||||
if let completion = completion {
|
||||
completion(result)
|
||||
}
|
||||
|
||||
@ -9,8 +9,12 @@ private final class SwitchNodeViewLayer: CALayer {
|
||||
|
||||
private final class SwitchNodeView: UISwitch {
|
||||
override class var layerClass: AnyClass {
|
||||
if #available(iOS 26.0, *) {
|
||||
return super.layerClass
|
||||
} else {
|
||||
return SwitchNodeViewLayer.self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class SwitchNode: ASDisplayNode {
|
||||
@ -82,8 +86,12 @@ open class SwitchNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
override open func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
if #available(iOS 26.0, *) {
|
||||
return CGSize(width: 63.0, height: 28.0)
|
||||
} else {
|
||||
return CGSize(width: 51.0, height: 31.0)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func switchValueChanged(_ view: UISwitch) {
|
||||
self._isOn = view.isOn
|
||||
|
||||
@ -11,6 +11,8 @@ typedef enum {
|
||||
+ (void)swizzleInstanceMethodOfClass:(Class _Nonnull)targetClass currentSelector:(SEL _Nonnull)currentSelector newSelector:(SEL _Nonnull)newSelector;
|
||||
+ (void)swizzleInstanceMethodOfClass:(Class _Nonnull)targetClass currentSelector:(SEL _Nonnull)currentSelector withAnotherClass:(Class _Nonnull)anotherClass newSelector:(SEL _Nonnull)newSelector;
|
||||
+ (void)swizzleClassMethodOfClass:(Class _Nonnull)targetClass currentSelector:(SEL _Nonnull)currentSelector newSelector:(SEL _Nonnull)newSelector;
|
||||
+ (void * _Nullable)getMethodOfClass:(Class _Nonnull)targetClass selector:(SEL _Nonnull)selector;
|
||||
+ (void)replaceMethodImplementationOfClass:(Class _Nonnull)targetClass selector:(SEL _Nonnull)selector replacement:(IMP _Nonnull)replacement;
|
||||
+ (CALayer * _Nonnull)makeLayerHostCopy:(CALayer * _Nonnull)another;
|
||||
|
||||
@end
|
||||
@ -30,3 +32,4 @@ typedef enum {
|
||||
@end
|
||||
|
||||
SEL _Nonnull makeSelectorFromString(NSString * _Nonnull string);
|
||||
|
||||
|
||||
@ -59,6 +59,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ (void * _Nullable)getMethodOfClass:(Class _Nonnull)targetClass selector:(SEL _Nonnull)selector {
|
||||
return class_getInstanceMethod(targetClass, selector);
|
||||
}
|
||||
|
||||
+ (void)replaceMethodImplementationOfClass:(Class _Nonnull)targetClass selector:(SEL _Nonnull)selector replacement:(IMP _Nonnull)replacement {
|
||||
Method method = class_getInstanceMethod(targetClass, selector);
|
||||
if (method) {
|
||||
method_setImplementation(method, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSObject (AssociatedObject)
|
||||
|
||||
@ -33,9 +33,9 @@ open class ChatInputPanelNode: ASDisplayNode {
|
||||
|
||||
open func defaultHeight(metrics: LayoutMetrics) -> CGFloat {
|
||||
if case .regular = metrics.widthClass, case .regular = metrics.heightClass {
|
||||
return 49.0
|
||||
return 40.0
|
||||
} else {
|
||||
return 45.0
|
||||
return 40.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ swift_library(
|
||||
"//submodules/Display",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/Components/ComponentDisplayAdapters",
|
||||
"//submodules/UIKitRuntimeUtils",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@ -3,6 +3,7 @@ import UIKit
|
||||
import Display
|
||||
import ComponentFlow
|
||||
import ComponentDisplayAdapters
|
||||
import UIKitRuntimeUtils
|
||||
|
||||
private final class ContentContainer: UIView {
|
||||
private let maskContentView: UIView
|
||||
@ -273,6 +274,7 @@ public class GlassBackgroundView: UIView {
|
||||
private let backgroundNode: NavigationBackgroundNode?
|
||||
private let nativeView: UIVisualEffectView?
|
||||
private let nativeContainerView: UIVisualEffectView?
|
||||
private let nativeParamsView: EffectSettingsContainerView?
|
||||
|
||||
private let foregroundView: UIImageView?
|
||||
private let shadowView: UIImageView?
|
||||
@ -305,13 +307,20 @@ public class GlassBackgroundView: UIView {
|
||||
self.nativeContainerView = nativeContainerView
|
||||
nativeContainerView.contentView.addSubview(nativeView)
|
||||
|
||||
let nativeParamsView = EffectSettingsContainerView(frame: CGRect())
|
||||
self.nativeParamsView = nativeParamsView
|
||||
|
||||
nativeParamsView.addSubview(nativeContainerView)
|
||||
|
||||
self.foregroundView = nil
|
||||
self.shadowView = nil
|
||||
} else {
|
||||
self.backgroundNode = NavigationBackgroundNode(color: .black, enableBlur: true, customBlurRadius: 5.0)
|
||||
self.nativeView = nil
|
||||
self.nativeContainerView = nil
|
||||
self.nativeParamsView = nil
|
||||
self.foregroundView = UIImageView()
|
||||
|
||||
self.shadowView = UIImageView()
|
||||
}
|
||||
|
||||
@ -331,8 +340,8 @@ public class GlassBackgroundView: UIView {
|
||||
if let shadowView = self.shadowView {
|
||||
self.addSubview(shadowView)
|
||||
}
|
||||
if let nativeContainerView = self.nativeContainerView {
|
||||
self.addSubview(nativeContainerView)
|
||||
if let nativeParamsView = self.nativeParamsView {
|
||||
self.addSubview(nativeParamsView)
|
||||
}
|
||||
if let backgroundNode = self.backgroundNode {
|
||||
self.addSubview(backgroundNode.view)
|
||||
@ -372,7 +381,7 @@ public class GlassBackgroundView: UIView {
|
||||
nativeView.layer.animateFrame(from: previousFrame, to: CGRect(origin: CGPoint(), size: size), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
}
|
||||
|
||||
transition.setFrame(view: nativeContainerView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
transition.setFrame(view: nativeContainerView, frame: CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: max(size.height, 400.0))))
|
||||
}
|
||||
if let backgroundNode = self.backgroundNode {
|
||||
backgroundNode.updateColor(color: .clear, forceKeepBlur: tintColor.color.alpha != 1.0, transition: transition.containedViewLayoutTransition)
|
||||
@ -404,7 +413,7 @@ public class GlassBackgroundView: UIView {
|
||||
if let foregroundView = self.foregroundView {
|
||||
foregroundView.image = GlassBackgroundView.generateLegacyGlassImage(size: CGSize(width: cornerRadius * 2.0, height: cornerRadius * 2.0), inset: shadowInset, isDark: isDark, fillColor: tintColor.color)
|
||||
} else {
|
||||
if let nativeContainerView = self.nativeContainerView, let nativeView {
|
||||
if let nativeParamsView = self.nativeParamsView, let nativeContainerView = self.nativeContainerView, let nativeView {
|
||||
if #available(iOS 26.0, *) {
|
||||
let glassEffect = UIGlassEffect(style: .regular)
|
||||
switch tintColor.kind {
|
||||
@ -416,9 +425,16 @@ public class GlassBackgroundView: UIView {
|
||||
glassEffect.isInteractive = params.isInteractive
|
||||
|
||||
nativeView.effect = glassEffect
|
||||
let _ = nativeContainerView
|
||||
//nativeContainerView.overrideUserInterfaceStyle = .light// isDark ? .dark : .light
|
||||
self.overrideUserInterfaceStyle = isDark ? .dark : .light
|
||||
|
||||
if isDark {
|
||||
nativeParamsView.lumaMin = 0.0
|
||||
nativeParamsView.lumaMax = 0.15
|
||||
} else {
|
||||
nativeParamsView.lumaMin = 0.25
|
||||
nativeParamsView.lumaMax = 1.0
|
||||
}
|
||||
|
||||
nativeContainerView.overrideUserInterfaceStyle = isDark ? .dark : .light
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -665,7 +681,6 @@ public extension GlassBackgroundView {
|
||||
addShadow(false, CGPoint(x: 3.0, y: -3.0), 2.0, 0.0, UIColor(white: 1.0, alpha: 0.25), false)
|
||||
addShadow(false, CGPoint(x: -3.0, y: 3.0), 2.0, 0.0, UIColor(white: 1.0, alpha: 0.25), false)
|
||||
} else {
|
||||
addShadow(true, CGPoint(), 32.0, 0.0, UIColor(white: 0.0, alpha: 0.08), false)
|
||||
addShadow(true, CGPoint(), 16.0, 0.0, UIColor(white: 0.0, alpha: 0.08), false)
|
||||
|
||||
context.setFillColor(fillColor.cgColor)
|
||||
@ -673,17 +688,18 @@ public extension GlassBackgroundView {
|
||||
|
||||
let highlightColor: UIColor
|
||||
if fillColor.hsb.s > 0.5 {
|
||||
highlightColor = fillColor.withMultiplied(hue: 1.0, saturation: 2.0, brightness: 1.0).adjustedPerceivedBrightness(2.0)
|
||||
var (h, s, v) = fillColor.hsb
|
||||
s = max(0.0, min(1.0, s * 0.25))
|
||||
v = max(v, 0.95)
|
||||
h = max(0.0, min(1.0, h - 0.1))
|
||||
|
||||
let shadowColor = fillColor.withMultiplied(hue: 1.0, saturation: 2.0, brightness: 1.0).adjustedPerceivedBrightness(0.5).withMultipliedAlpha(0.2)
|
||||
addShadow(false, CGPoint(x: -2.0, y: 2.0), 0.5, 0.0, shadowColor, false)
|
||||
highlightColor = UIColor(hue: h, saturation: s, brightness: v, alpha: fillColor.alpha)
|
||||
} else {
|
||||
highlightColor = UIColor(white: 1.0, alpha: 0.4)
|
||||
addShadow(false, CGPoint(x: -2.0, y: 2.0), 0.5, 0.0, UIColor.black.withMultipliedAlpha(0.15), true)
|
||||
addShadow(false, CGPoint(x: -2.0, y: 2.0), 0.6, 0.0, UIColor(white: 0.0, alpha: 0.1), false)
|
||||
highlightColor = UIColor(white: 1.0, alpha: min(1.0, fillColor.alpha * 1.2))
|
||||
}
|
||||
|
||||
addShadow(false, CGPoint(x: 2.0, y: -2.0), 0.5, 0.0, highlightColor, false)
|
||||
addShadow(false, CGPoint(x: 2.0, y: -2.0), 1.0, 0.0, highlightColor, false)
|
||||
addShadow(false, CGPoint(x: -2.0, y: 2.0), 1.0, 0.0, highlightColor, false)
|
||||
}
|
||||
})!.stretchableImage(withLeftCapWidth: Int(size.width * 0.5), topCapHeight: Int(size.height * 0.5))
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ final class ChatHistoryNavigationButtons: ASDisplayNode {
|
||||
transition.updateAlpha(node: self.downButton, alpha: 1.0)
|
||||
transition.updateTransformScale(node: self.downButton, scale: 1.0)
|
||||
} else {
|
||||
transition.updateAlpha(node: self.downButton, alpha: 0.1, completion: { [weak self] completed in
|
||||
transition.updateAlpha(node: self.downButton, alpha: 0.0, completion: { [weak self] completed in
|
||||
guard let strongSelf = self, completed else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -279,9 +279,9 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
|
||||
|
||||
let height: CGFloat
|
||||
if case .regular = params.metrics.widthClass {
|
||||
height = 49.0
|
||||
height = 40.0
|
||||
} else {
|
||||
height = 45.0
|
||||
height = 40.0
|
||||
}
|
||||
|
||||
var modeButtonTitle: [AnimatedTextComponent.Item] = []
|
||||
|
||||
@ -57,3 +57,10 @@ void applyKeyboardAutocorrection(UITextView * _Nonnull textView);
|
||||
@end
|
||||
|
||||
void snapshotViewByDrawingInContext(UIView * _Nonnull view);
|
||||
|
||||
@interface EffectSettingsContainerView : UIView
|
||||
|
||||
@property (nonatomic) double lumaMin;
|
||||
@property (nonatomic) double lumaMax;
|
||||
|
||||
@end
|
||||
|
||||
@ -173,6 +173,59 @@ static bool notyfyingShiftState = false;
|
||||
|
||||
@end
|
||||
|
||||
static EffectSettingsContainerView *findTopmostEffectSuperview(UIView *view, int depth) {
|
||||
if (depth > 5) {
|
||||
return nil;
|
||||
}
|
||||
if ([view isKindOfClass:[EffectSettingsContainerView class]]) {
|
||||
return (EffectSettingsContainerView* )view;
|
||||
}
|
||||
if (view.superview != nil) {
|
||||
return findTopmostEffectSuperview(view.superview, depth + 1);
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
static id (*original_backdropLayerDidChangeLuma)(UIView *, SEL, CALayer *, double) = NULL;
|
||||
static void replacement_backdropLayerDidChangeLuma(UIView *self, SEL selector, CALayer *layer, double luma) {
|
||||
EffectSettingsContainerView *topmostSuperview = findTopmostEffectSuperview(self, 0);
|
||||
if (topmostSuperview) {
|
||||
luma = MIN(MAX(luma, topmostSuperview.lumaMin), topmostSuperview.lumaMax);
|
||||
}
|
||||
original_backdropLayerDidChangeLuma(self, selector, layer, luma);
|
||||
}
|
||||
|
||||
static void registerEffectViewOverrides(void) {
|
||||
int classCount = objc_getClassList(NULL, 0);
|
||||
if (classCount > 0) {
|
||||
__unsafe_unretained Class *classList = (Class *)malloc(classCount * sizeof(Class));
|
||||
objc_getClassList(classList, classCount);
|
||||
|
||||
NSString *searchString = [@"UISD" stringByAppendingString:@"FBackdropView"];
|
||||
NSString *selectorString = [@"backdropLayer" stringByAppendingString:@":didChangeLuma:"];
|
||||
|
||||
for (int i = 0; i < classCount; i++)
|
||||
{
|
||||
const char *className = class_getName(classList[i]);
|
||||
NSString *name = [[NSString alloc] initWithCString:className encoding:NSASCIIStringEncoding];
|
||||
if ([name hasSuffix:searchString]) {
|
||||
Method method = (Method)[RuntimeUtils getMethodOfClass:classList[i] selector:NSSelectorFromString(selectorString)];
|
||||
if (method) {
|
||||
const char *typeEncoding = method_getTypeEncoding(method);
|
||||
if (strcmp(typeEncoding, "v32@0:8@16d24") == 0) {
|
||||
original_backdropLayerDidChangeLuma = (id (*)(id, SEL, CALayer *, double))method_getImplementation(method);
|
||||
[RuntimeUtils replaceMethodImplementationOfClass:classList[i] selector:NSSelectorFromString(selectorString) replacement:(IMP)&replacement_backdropLayerDidChangeLuma];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(classList);
|
||||
}
|
||||
}
|
||||
|
||||
@implementation UIViewController (Navigation)
|
||||
|
||||
+ (void)load
|
||||
@ -197,6 +250,10 @@ static bool notyfyingShiftState = false;
|
||||
}
|
||||
|
||||
[RuntimeUtils swizzleInstanceMethodOfClass:[UIFocusSystem class] currentSelector:@selector(updateFocusIfNeeded) newSelector:@selector(_65087dc8_updateFocusIfNeeded)];
|
||||
|
||||
if (@available(iOS 26.0, *)) {
|
||||
registerEffectViewOverrides();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -501,3 +558,16 @@ void applyKeyboardAutocorrection(UITextView * _Nonnull textView) {
|
||||
void snapshotViewByDrawingInContext(UIView * _Nonnull view) {
|
||||
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:false];
|
||||
}
|
||||
|
||||
@implementation EffectSettingsContainerView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self != nil) {
|
||||
_lumaMin = 0.0;
|
||||
_lumaMax = 0.0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user