恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

IOS27 适配 手势滑动返回导航栏向上飘

  • 首页
  • 资讯中心
  • /
  • IOS27 适配 手势滑动返回导航栏向上飘

相关资讯

印刷包装厂用电销接单,怎么让每通报价都有下文 2026/9/30 7:10:50
企业税务咨询|合规前置,筑牢企业经营底气 2026/9/30 7:05:50
Flink 优化之 CheckPoint 优化及参数详解:从原理到生产环境调优的完整指南 2026/9/30 7:05:50

最新资讯

前端深色模式与主题切换:CSS变量、三态与首屏防闪烁
AI资讯追踪方法论:从信息分类到RSS工作流的高效实践指南
内幕消息是陷阱:利弗莫尔在“联合炉具”中反手做空的启示
从断网到懂网:TCP/IP、DNS与网络排查实战笔记
Harbor私有镜像仓库部署及使用教程
Tracker响应速度优化:全国联通线路拨测与服务器调优实践

今日推荐

模型优化器实战:从FP32到INT8的推理加速与精度平衡
LangGraph+FastAPI构建可审计AI编码助手
基于图像预处理与几何特征的人脸脸型发型搭配系统实现

本周热门

从像素到笔画:srt-whiteboard-animation骨架笔迹追踪实现(Zhang-Suen细化+8邻接追踪)
网站建设的英语怎么说?别只背单词,看完这套安全完整流程才敢上线
新手入门看这篇:建设网站加盟避坑指南与SEO实操

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

IOS27 适配 手势滑动返回导航栏向上飘

发布时间:2026/9/30 7:10:50
IOS27 适配 手势滑动返回导航栏向上飘 其实真的那个液态UI很丑。。并不好看。。但是IOS27直接彻底关闭了UIDesignRequiresCompatibility兼容APP只能进行全方位适配1、更新xcode后项目无法启动表现为项目目录左侧点击项目名称右侧切换general选项标签时直接崩处理方法删除info.plist文件中的此KEY现在原因不知道为何很烂很烂。。。keyNSLocationTemporaryUsageDescriptionDictionary/key dict keypurposeKey4changeInfo/key string允许使用精确的定位功能,以便考勤打卡?/string /dict2、UIWindow的初始化及管理如最新SDK实现window已经被补刀避免后期再次出现补刀有必要抽出来实现一个子类这样做的好处是后面有调整直接在子类实现另一个就是Appdelegatge已经不允许初始化UIWindow而是放在了SceneDelegate所以导致全局读取window的方法也失效所以这里也有必要暴露一个方法来全面替换之前通过[[[UIApplication sharedApplication] delegate] window]来读取的代码// // UIRootWindow.h // // Created by carbonzhao on 2024/3/21. // #import UIKit/UIKit.h NS_ASSUME_NONNULL_BEGIN interface UIRootWindow : UIWindow //出现控制器推出显示时显示在window上的view会被移除 (void)addSubview:(UIView *)view; //出现控制器推出显示时显示在window上的view不会被移除 (void)addAliveSubview:(UIView *)view; (void)sendSubviewToBack:(UIView *)view; (UIView *)viewWithTag:(NSInteger)tag; (void)dissmiss:(void (^)(void))callback; (UIRootWindow *)window; (UIWindow *)keyWindow; end NS_ASSUME_NONNULL_END// // UIRootWindow.m // // Created by carbonzhao on 2024/3/21. // #import UIRootWindow.h #import objc/runtime.h #import NSObjectDYSwizzle.h interface NSWindowStack : NSObject property (nonatomic,weak) UIView *subView; end implementation NSWindowStack end interface RootWindowWatcher : NSObject property (nonatomic,weak) UIRootWindow *aWindow; property (nonatomic, strong) NSMutableArray NSWindowStack * *subviews; (RootWindowWatcher *)instance; end implementation RootWindowWatcher - (instancetype)init { if (self [super init]) { self.subviews [NSMutableArray arrayWithCapacity:0]; } return self; } (RootWindowWatcher *)instance { static RootWindowWatcher *watcher nil; static dispatch_once_t onceToken; dispatch_once(onceToken, ^{ watcher [[RootWindowWatcher alloc] init]; }); return watcher; } - (UIRootWindow *)aWindow { UIWindow *window _aWindow; if (!window) { if (available(iOS 13.0, *)) { for (UIWindowScene* windowScene in [UIApplication sharedApplication].connectedScenes) { if (windowScene.activationState UISceneActivationStateForegroundActive) { window windowScene.windows.firstObject; break; } } } else { window [UIApplication sharedApplication].keyWindow; } } return window; } end interface UIView (swizzle) end implementation UIView (swizzle) (void)load { static dispatch_once_t onceToken; dispatch_once(onceToken, ^{ Class class self; [class swizzleSEL:selector(removeFromSuperview) withSEL:selector(ae_removeFromSuperview)]; }); } - (void)ae_removeFromSuperview { [self ae_removeFromSuperview]; //只针对标记的VIEW if (objc_getAssociatedObject(self, com.extention.viewKey)) { NSMutableArray *alist [NSMutableArray arrayWithCapacity:0]; [[[RootWindowWatcher instance] subviews] enumerateObjectsUsingBlock:^(NSWindowStack *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { if (obj.subView obj.subView ! self) { [alist addObject:obj]; } }]; [[RootWindowWatcher instance] setSubviews:alist]; } } end interface UIViewController (swizzle) end implementation UIViewController (swizzle) (void)load { static dispatch_once_t onceToken; dispatch_once(onceToken, ^{ Class class self; [class swizzleSEL:selector(presentViewController:animated:completion:) withSEL:selector(ae_presentViewController:animated:completion:)]; [class swizzleSEL:selector(presentModalViewController:animated:) withSEL:selector(ae_presentModalViewController:animated:)]; }); } - (void)ae_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { [UIRootWindow dissmiss:nil]; [self ae_presentViewController:viewControllerToPresent animated:flag completion:completion]; } - (void)ae_presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated { [UIRootWindow dissmiss:nil]; [self ae_presentModalViewController:modalViewController animated:animated]; } end interface UINavigationController (swizzle) end implementation UINavigationController (swizzle) (void)load { static dispatch_once_t onceToken; dispatch_once(onceToken, ^{ Class class self; [class swizzleSEL:selector(pushViewController:animated:) withSEL:selector(be_pushViewController:animated:)]; }); } - (void)be_pushViewController:(UIViewController *)viewController animated:(BOOL)animated { __weak typeof(self) weakSelf self; [UIRootWindow dissmiss:^{ [weakSelf be_pushViewController:viewController animated:animated]; }]; } end implementation UIRootWindow - (instancetype)initWithFrame:(CGRect)frame { if (self [super initWithFrame: frame]) { [[RootWindowWatcher instance] setAWindow:self]; } return self; } - (instancetype)initWithWindowScene:(UIWindowScene *)windowScene { if (self [super initWithWindowScene: windowScene]) { [[RootWindowWatcher instance] setAWindow:self]; } return self; } (void)addSubview:(UIView *)view { //对view进行标记后续处理只针对标记的VIEW if (view) { objc_setAssociatedObject(view, com.extention.viewKey, 1, OBJC_ASSOCIATION_RETAIN_NONATOMIC); NSWindowStack *s [[NSWindowStack alloc] init]; [s setSubView:view]; [[RootWindowWatcher instance].subviews addObject:s]; [[RootWindowWatcher instance].aWindow addSubview:view]; } } (void)addAliveSubview:(UIView *)view { if (view) { [[RootWindowWatcher instance].aWindow addSubview:view]; } } (void)sendSubviewToBack:(UIView *)view { [[RootWindowWatcher instance].aWindow sendSubviewToBack:view]; } //- (void)dissmissWithPushAanimation //{ // [[[RootWindowWatcher instance] subviews] enumerateObjectsUsingBlock:^(NSWindowStack *_Nonnull aobj, NSUInteger idx, BOOL *_Nonnull stop) // { // if ([aobj subView]) // { // [UIView animateWithDuration:0.5 animations:^{ // CGRect frame [aobj subView].frame; // frame.origin.x -[aobj subView].frame.size.width; // [aobj subView].frame frame; // } completion:^(BOOL finished) { // [[aobj subView] removeFromSuperview]; // }]; // } // }]; //} //- (void)dissmissWithModalAanimation //{ // [[[RootWindowWatcher instance] subviews] enumerateObjectsUsingBlock:^(NSWindowStack *_Nonnull aobj, NSUInteger idx, BOOL *_Nonnull stop) // { // if ([aobj subView]) // { // [UIView animateWithDuration:0.25 animations:^{ // [[aobj subView] setAlpha:.0]; // [aobj subView].transformCGAffineTransformMakeScale(0.01, 0.01); // } completion:^(BOOL finished) { // [[aobj subView] removeFromSuperview]; // }]; // } // }]; //} - (void)dissmiss:(void (^)(void))callback { if ([[RootWindowWatcher instance] subviews].count 0) { [[[RootWindowWatcher instance] subviews] enumerateObjectsUsingBlock:^(NSWindowStack *_Nonnull aobj, NSUInteger idx, BOOL *_Nonnull stop) { UIView *lastView [[aobj subView] isKindOfClass:[UIView class]]?[[[aobj subView] subviews] lastObject]:[aobj subView]; if (lastView) { if (lastView.frame.origin.x [[UIScreen mainScreen] bounds].size.width/2 lastView.frame.size.height [[UIScreen mainScreen] bounds].size.height/2) { [UIView animateWithDuration:0.25 animations:^{ [aobj subView].backgroundColor [UIColor clearColor]; CGRect frame lastView.frame; frame.origin.x -lastView.frame.size.width; lastView.frame frame; } completion:^(BOOL finished) { if (callback) { callback(); } [[aobj subView] removeFromSuperview]; }]; } else if (lastView.frame.origin.x 0 lastView.frame.size.height [[UIScreen mainScreen] bounds].size.height/2) { [UIView animateWithDuration:0.25 animations:^{ [aobj subView].backgroundColor [UIColor clearColor]; CGRect frame [aobj subView].frame; frame.origin.x [UIScreen mainScreen].bounds.size.width; [aobj subView].frame frame; } completion:^(BOOL finished) { if (callback) { callback(); } [[aobj subView] removeFromSuperview]; }]; } else if (lastView.center.y [[UIScreen mainScreen] bounds].size.height/3) { [UIView animateWithDuration:.2 delay:0 usingSpringWithDamping:1 initialSpringVelocity:0 options:UIViewAnimationOptionTransitionCurlUp animations:^ { CGRect frame [aobj subView].frame; frame.origin.y -[aobj subView].frame.size.height; [aobj subView].frame frame; [[[aobj subView] subviews].firstObject setAlpha:.0]; } completion:^(BOOL finished) { if (callback) { callback(); } [[aobj subView] removeFromSuperview]; }]; } else if (lastView.center.y [[UIScreen mainScreen] bounds].size.height*2/3) { [UIView animateWithDuration:0.25 animations:^{ [[[aobj subView] subviews].firstObject setAlpha:.0]; [aobj subView].transformCGAffineTransformMakeScale(0.01, 0.01); } completion:^(BOOL finished) { if (callback) { callback(); } [[aobj subView] removeFromSuperview]; }]; } else { [UIView animateWithDuration:.25 delay:0 usingSpringWithDamping:1 initialSpringVelocity:0 options:UIViewAnimationOptionTransitionCurlDown animations:^ { CGRect frame lastView.frame; frame.origin.y [[UIScreen mainScreen] bounds].size.height; lastView.frame frame; [[[aobj subView] subviews].firstObject setAlpha:.0]; } completion:^(BOOL finished) { if (callback) { callback(); } [[aobj subView] removeFromSuperview]; }]; } } }]; } else { if (callback) { callback(); } } } // (void)dissmissWithPushAanimation //{ // if ([RootWindowWatcher instance].aWindow) // { // [[RootWindowWatcher instance].aWindow dissmissWithPushAanimation]; // } //} // (void)dissmissWithModalAanimation //{ // if ([RootWindowWatcher instance].aWindow) // { // [[RootWindowWatcher instance].aWindow dissmissWithModalAanimation]; // } //} (void)dissmiss:(void (^)(void))callback { if ([RootWindowWatcher instance].aWindow [[RootWindowWatcher instance].aWindow isKindOfClass:[UIRootWindow class]]) { [[RootWindowWatcher instance].aWindow dissmiss:callback]; } else { if (callback) { callback(); } } } (UIView *)viewWithTag:(NSInteger)tag { return [[RootWindowWatcher instance].aWindow viewWithTag:tag]; } (UIRootWindow *)window{ return [RootWindowWatcher instance].aWindow; } (UIWindow *)keyWindow { UIWindow *keyWindow nil; #if __IPHONE_OS_VERSION_MAX_ALLOWED 130000 // 编译时检查SDK版本Xcode11编译会调用iOS SDK 13.0 以后版本的处理 if (available(iOS 13.0, *)) { NSSetUIScene * *connectedScenes [UIApplication sharedApplication].connectedScenes; for (UIScene *scene in connectedScenes) { if (scene.activationState UISceneActivationStateForegroundActive [scene isKindOfClass:[UIWindowScene class]]) { UIWindowScene *windowScene (UIWindowScene *)scene; for (UIWindow *window in windowScene.windows) { if (window.isKeyWindow) { keyWindow window; break; } } } } } else #endif { #if __IPHONE_OS_VERSION_MIN_REQUIRED 130000 return [UIApplication sharedApplication].keyWindow; #endif } return keyWindow; } end3、创建新的窗口管理类3.1在项目的info.plist文件中新增以下节点数据keyUIApplicationSceneManifest/key dict keyUIApplicationSupportsMultipleScenes/key false/ keyUISceneConfigurations/key dict keyUIWindowSceneSessionRoleApplication/key array dict keyUISceneConfigurationName/key stringDefault Configuration/string keyUISceneDelegateClassName/key stringSceneDelegate/string /dict /array /dict /dict3.2 AppDelegate同目录创建SceneDelegate类// // SceneDelegate.h // // Created by carbonzhao on 2026/9/18. // Copyright © 2026. All rights reserved. // #import UIKit/UIKit.h #import UIRootWindow.h NS_ASSUME_NONNULL_BEGIN interface SceneDelegate : UIResponder UIWindowSceneDelegate property (strong, nonatomic) UIRootWindow * window; property (strong, nonatomic) QGBTabBarController *tabBarController; end NS_ASSUME_NONNULL_END// // SceneDelegate.m // // Created by carbonzhao on 2026/9/18. // Copyright © 2026. All rights reserved. // #import SceneDelegate.h interface SceneDelegate () end implementation SceneDelegate - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { // Use this method to optionally configure and attach the UIWindow window to the provided UIWindowScene scene. // If using a storyboard, the window property will automatically be initialized and attached to the scene. // This delegate does not imply the connecting scene or session are new (see application:configurationForConnectingSceneSession instead). //如果第一次启动则弹出用户隐私政策及用户协议 UIWindowScene *windowScene (UIWindowScene *)scene; self.window [[UIRootWindow alloc] initWithWindowScene:windowScene]; [self.window makeKeyAndVisible]; } - (void)sceneDidDisconnect:(UIScene *)scene { // Called as the scene is being released by the system. // This occurs shortly after the scene enters the background, or when its session is discarded. // Release any resources associated with this scene that can be re-created the next time the scene connects. // The scene may re-connect later, as its session was not necessarily discarded (see application:didDiscardSceneSessions instead). } - (void)sceneDidBecomeActive:(UIScene *)scene { // Called when the scene has moved from an inactive state to an active state. // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. if ([UIApplication sharedApplication].delegate [[UIApplication sharedApplication].delegate respondsToSelector:selector(applicationDidBecomeActive:)]) { [[[UIApplication sharedApplication] delegate] applicationDidBecomeActive:[UIApplication sharedApplication]]; } } - (void)sceneWillResignActive:(UIScene *)scene { // Called when the scene will move from an active state to an inactive state. // This may occur due to temporary interruptions (ex. an incoming phone call). if ([UIApplication sharedApplication].delegate [[UIApplication sharedApplication].delegate respondsToSelector:selector(applicationWillResignActive:)]) { [[[UIApplication sharedApplication] delegate] applicationWillResignActive:[UIApplication sharedApplication]]; } } - (void)sceneWillEnterForeground:(UIScene *)scene { // Called as the scene transitions from the background to the foreground. // Use this method to undo the changes made on entering the background. if ([UIApplication sharedApplication].delegate [[UIApplication sharedApplication].delegate respondsToSelector:selector(applicationWillEnterForeground:)]) { [[[UIApplication sharedApplication] delegate] applicationWillEnterForeground:[UIApplication sharedApplication]]; } } - (void)sceneDidEnterBackground:(UIScene *)scene { // Called as the scene transitions from the foreground to the background. // Use this method to save data, release shared resources, and store enough scene-specific state information // to restore the scene back to its current state. if ([UIApplication sharedApplication].delegate [[UIApplication sharedApplication].delegate respondsToSelector:selector(applicationDidEnterBackground:)]) { [[[UIApplication sharedApplication] delegate] applicationDidEnterBackground:[UIApplication sharedApplication]]; } } end其实这里也可以不必将UIWindow的初始化迁移到新建的SceneDelegate而是在AppDelegate新增一个方法在SceneDelegate调用来初始化即可这样仍然可以保留原有代码位置不至于让代码看着松散难受。具体你视你们要求而定。如我的做法4、AppDelegate的适配删除所有UIWindow的alloc地方将其移动到新的SceneDelegate的以下方法中同时使用上述实现的UIRootWindow来初始化及实现- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { // Use this method to optionally configure and attach the UIWindow window to the provided UIWindowScene scene. // If using a storyboard, the window property will automatically be initialized and attached to the scene. // This delegate does not imply the connecting scene or session are new (see application:configurationForConnectingSceneSession instead). UIWindowScene *windowScene (UIWindowScene *)scene; self.window [[UIRootWindow alloc] initWithWindowScene:windowScene]; [self.window makeKeyAndVisible]; //移植你之前的逻辑 self.window.rootViewController XXX }此文件中以下4个方法如果有实现逻辑在SceneDelegate对应的方法中调用具体见上述3中的实现避免大量迁移代码官方文档Transitioning to the UIKit scene-based life cycle | Apple Developer Documentation5、UITabbarcontroller自定义的适配- (void)viewDidLoad { [super viewDidLoad]; //CYLTabBar继承于UITabbar CYLTabBar *aBar [[CYLTabBar alloc] init]; [self setValue:aBar forKey:tabBar]; }//CYLTabBar实现父类方法若发现在添加_UITabBarPlatterView直接忽略则相当于间接拒绝了新增的交互及UI - (void)addSubview:(UIView *)view { if (![view isKindOfClass:NSClassFromString(UITabBarButton)] ![view isKindOfClass:NSClassFromString(UIKit._UITabBarPlatterView)]) { [super addSubview:view]; } }若非自定义tabbar则思路一致你直接进行实现即可6、导航栏左、右barbutton的适配interface UINavigationItem (ios27) endvoid aeMethodSwizzle(Class c,SEL origSEL,SEL overrideSEL) { Method origMethod class_getInstanceMethod(c, origSEL); Method overrideMethod class_getInstanceMethod(c, overrideSEL); //运行时函数class_addMethod 如果发现方法已经存在会失败返回也可以用来做检查用: if(class_addMethod(c, origSEL, method_getImplementation(overrideMethod),method_getTypeEncoding(overrideMethod))) { //如果添加成功(在父类中重写的方法)再把目标类中的方法替换为旧有的实现: class_replaceMethod(c,overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); } else { //addMethod会让目标类的方法指向新的实现使用replaceMethod再将新的方法指向原先的实现这样就完成了交换操作。 method_exchangeImplementations(origMethod,overrideMethod); } } implementation UINavigationItem (ios27) (void)load { aeMethodSwizzle(self,selector(setLeftBarButtonItem:),selector(ae_setLeftBarButtonItem:)); aeMethodSwizzle(self,selector(setLeftBarButtonItem:animated:),selector(ae_setLeftBarButtonItem:animated:)); aeMethodSwizzle(self,selector(setLeftBarButtonItems:),selector(ae_setLeftBarButtonItems:)); aeMethodSwizzle(self,selector(setLeftBarButtonItems:animated:),selector(ae_setLeftBarButtonItems:animated:)); aeMethodSwizzle(self,selector(setRightBarButtonItem:),selector(ae_setRightBarButtonItem:)); aeMethodSwizzle(self,selector(setRightBarButtonItem:animated:),selector(ae_setRightBarButtonItem:animated:)); aeMethodSwizzle(self,selector(setRightBarButtonItems:),selector(ae_setRightBarButtonItems:)); aeMethodSwizzle(self,selector(setRightBarButtonItems:animated:),selector(ae_setRightBarButtonItems:animated:)); } - (void)ae_setLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem { leftBarButtonItem.hidesSharedBackground YES; leftBarButtonItem.sharesBackground NO; [self ae_setLeftBarButtonItem:leftBarButtonItem]; } - (void)ae_setLeftBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { item.hidesSharedBackground YES; item.sharesBackground NO; [self ae_setLeftBarButtonItem:item animated:animated]; } - (void)ae_setLeftBarButtonItems:(NSArrayUIBarButtonItem * *)leftBarButtonItems { [leftBarButtonItems enumerateObjectsUsingBlock:^(UIBarButtonItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { obj.hidesSharedBackground YES; obj.sharesBackground NO; }]; [self ae_setLeftBarButtonItems:leftBarButtonItems]; } - (void)ae_setLeftBarButtonItems:(NSArrayUIBarButtonItem * *)leftBarButtonItems animated:(BOOL)animated { [leftBarButtonItems enumerateObjectsUsingBlock:^(UIBarButtonItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { obj.hidesSharedBackground YES; obj.sharesBackground NO; }]; [self ae_setLeftBarButtonItems:leftBarButtonItems animated:animated]; } - (void)ae_setRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem { rightBarButtonItem.hidesSharedBackground YES; rightBarButtonItem.sharesBackground NO; [self ae_setRightBarButtonItem:rightBarButtonItem]; } - (void)ae_setRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem animated:(BOOL)animated { rightBarButtonItem.hidesSharedBackground YES; rightBarButtonItem.sharesBackground NO; [self ae_setRightBarButtonItem:rightBarButtonItem animated:animated]; } - (void)ae_setRightBarButtonItems:(NSArrayUIBarButtonItem * *)rightBarButtonItems { [rightBarButtonItems enumerateObjectsUsingBlock:^(UIBarButtonItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { obj.hidesSharedBackground YES; obj.sharesBackground NO; }]; [self ae_setRightBarButtonItems:rightBarButtonItems]; } - (void)ae_setRightBarButtonItems:(NSArrayUIBarButtonItem * *)rightBarButtonItems animated:(BOOL)animated { [rightBarButtonItems enumerateObjectsUsingBlock:^(UIBarButtonItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { obj.hidesSharedBackground YES; obj.sharesBackground NO; }]; [self ae_setRightBarButtonItems:rightBarButtonItems animated:animated]; } end7、手势滑动返回导航栏向上飘经过调试发现在ios27上手势滑动返回的时候系统私有API在调用setCenter方法来修改UINavigationBar的center坐标。这里考虑一下为啥没用调用setFrame方法那就简单了 我们重载这个方法修正center.y值不让发生变化即可再配合Alpha来动态显隐达到修正的目的。interface UINavigationBar (adapter) endimplementation UINavigationBar (adapter) (void)load { if ([[[UIDevice currentDevice] systemVersion] floatValue] 27.0) { [self swizzleSEL:selector(setCenter:) withSEL:selector(sw_setCenter:)]; } } - (void)sw_setCenter:(CGPoint)pt { CGFloat t [UIRootWindow keyWindow].safeAreaInsets.top; CGFloat ot [UIRootWindow keyWindow].windowScene.statusBarManager.statusBarFrame.size.height / 2; CGFloat py pt.y; pt.y tot; if (py ! t ot) { // pt.x ScreenW() * fabs(py)/(tot) * 1.5; CGFloat alpha fabs(pt.y)/(tot); [self setAlpha:1-alpha]; } else { [self setAlpha:1]; } [self sw_setCenter:pt]; }

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号