当前位置: 首页 > news >正文

「OC」present和push操作区别以及混合推出的实现

「OC」present和push操作区别以及混合推出的实现

文章目录

  • 「OC」present和push操作区别以及混合推出的实现
    • 前言
    • present
      • 用途
      • while循环越级返回
      • 通知越级返回
      • 添加present动画
    • push
    • 模态视图和push视图混合跳转
      • 操作一:控制器A`present`控制器B,控制器B再将控制器C`push`出来
      • 操作二:控制器1push出控制器2,控制器2present控制器3,使用代理直接返回控制器1
    • 总结

前言

在viewController的生命周期之中,我们探究了present以及push不同操作之中,生命周期的方法调用,以及在暑假的时候学习了如何实现自定义模态视图和自定义模态视图动画。因此我继续探究present以及push操作的相关区别,以及学习如何实现视图的混合推出。

present

用途

用简单的几行代码先展示present的用途

ViewController* vc = [[ViewController alloc] init];
[self presentViewController:vc2 animated:YES completion:nil];

对应的dismiss方法

[self dismissViewControllerAnimated:YES completion:nil];

对于我们的present来说,我们的返回和进入都是逐级进行的,代码如下

ViewController1.h:

#import <UIKit/UIKit.h>@interface ViewController1 : UIViewController@end

ViewController1.m:

#import "ViewController1.h"
#import "ViewController2.h"@implementation ViewController1- (void)viewDidLoad {[super viewDidLoad];UIButton *presentButton = [UIButton buttonWithType:UIButtonTypeSystem];[presentButton setTitle:@"Present ViewController2" forState:UIControlStateNormal];[presentButton addTarget:self action:@selector(presentViewController2) forControlEvents:UIControlEventTouchUpInside];presentButton.frame = CGRectMake(100, 100, 200, 50);[self.view addSubview:presentButton];
}- (void)presentViewController2 {ViewController2 *vc2 = [[ViewController2 alloc] init];[self presentViewController:vc2 animated:YES completion:nil];
}@end

ViewController2.h:

#import <UIKit/UIKit.h>@interface ViewController2 : UIViewController@end

ViewController2.m:

#import "ViewController2.h"
#import "ViewController3.h"@implementation ViewController2- (void)viewDidLoad {[super viewDidLoad];UIButton *presentButton = [UIButton buttonWithType:UIButtonTypeSystem];[presentButton setTitle:@"Present ViewController3" forState:UIControlStateNormal];[presentButton addTarget:self action:@selector(presentViewController3) forControlEvents:UIControlEventTouchUpInside];presentButton.frame = CGRectMake(100, 200, 200, 50);[self.view addSubview:presentButton];
}- (void)presentViewController3 {ViewController3 *vc3 = [[ViewController3 alloc] init];[self presentViewController:vc3 animated:YES completion:nil];
}@end

ViewController3.h:

#import <UIKit/UIKit.h>@interface ViewController3 : UIViewController@end

ViewController3.m:

#import "ViewController3.h"@implementation ViewController3- (void)viewDidLoad {[super viewDidLoad];UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeSystem];[dismissButton setTitle:@"Dismiss" forState:UIControlStateNormal];[dismissButton addTarget:self action:@selector(dismissViewController) forControlEvents:UIControlEventTouchUpInside];dismissButton.frame = CGRectMake(100, 300, 200, 50);[self.view addSubview:dismissButton];
}- (void)dismissViewController {[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}@end

在这个示例中,控制器1包含一个按钮,点击后会present出控制器2。控制器2也包含一个按钮,点击后会present出控制器3。在控制器3中,点击按钮会通过dismiss方式逐级返回到前一个控制器,直到回到控制器1。

但是我们也可以用代码直接进行返回,这就要说到我们暑假自定义模态视图学习的关于presentedViewController以及presentingViewController的相关概念,即执行推出操作的上文来说为presentedViewController为被它推出的下文,执行推出操作的下文的presentingViewController为上文。

while循环越级返回

我已开始的设想是使用while循环,直到到达想要的控制器,我使用isKindOfClass的方法

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{UIViewController *currentViewController = self.presentingViewController;while (currentViewController) {if ([currentViewController isKindOfClass:[ViewController class]]) {// 找到所需的视图控制器ViewController *desiredViewController = (ViewController *)currentViewController;// 在这里执行dismiss操作[desiredViewController dismissViewControllerAnimated:YES completion:nil];break;}currentViewController = currentViewController.presentingViewController;}
}

实现的也是如下效果

Sep-18-2024 22-48-58

通知越级返回

可是这样直接进行遍历似乎还是有点麻烦,只要present的视图够多或者足够复杂的话,这样似乎会对性能造成一定的损伤,于是我用上了前段时间学习的通知传值来解决这个问题

  1. 在需要直接返回的地方发送通知,可以是任何一个视图控制器
[[NSNotificationCenter defaultCenter] postNotificationName:@"DirectReturnNotification" object:nil userInfo:@{@"targetViewController": @"ViewController1"}];
  1. 在需要响应直接返回的视图控制器中,监听通知并执行相应的返回操作。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handle:) name:@"DirectReturnNotification" object:nil];
}
  1. 接着写一下接受到通知之后的相关方法,我们这里用targetViewController的字符串区别一下不同的控制器
- (void)handleDirectReturnNotification:(NSNotification *)notification {NSString *targetViewController = notification.userInfo[@"targetViewController"];if ([targetViewController isEqualToString:@"ViewController2"]) {[self dismissViewControllerAnimated:YES completion:nil];}
}- (void)handleDirectReturnNotification:(NSNotification *)notification {NSString *targetViewController = notification.userInfo[@"targetViewController"];if ([targetViewController isEqualToString:@"ViewController1"]) {[self dismissViewControllerAnimated:YES completion:nil];}
}
  1. 控制器3的完整代码如下
#import "ViewController3.h"@interface ViewController3 ()@end@implementation ViewController3- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor greenColor];UIButton *returnButton1 = [UIButton buttonWithType:UIButtonTypeSystem];[returnButton1 setTitle:@"Direct Return to ViewController1" forState:UIControlStateNormal];[returnButton1 addTarget:self action:@selector(returnToViewController1) forControlEvents:UIControlEventTouchUpInside];returnButton1.frame = CGRectMake(100, 300, 200, 50);[self.view addSubview:returnButton1];UIButton *returnButton = [UIButton buttonWithType:UIButtonTypeSystem];[returnButton setTitle:@"Direct Return to ViewController2" forState:UIControlStateNormal];[returnButton addTarget:self action:@selector(returnToViewController2) forControlEvents:UIControlEventTouchUpInside];returnButton.frame = CGRectMake(100, 500, 200, 50);[self.view addSubview:returnButton];
}
- (void)returnToViewController1 {// 发送通知,指示需要直接返回到ViewController1[[NSNotificationCenter defaultCenter] postNotificationName:@"DirectReturnNotification" object:nil userInfo:@{@"targetViewController": @"ViewController1"}];
}
- (void)returnToViewController2 {// 发送通知,指示需要直接返回到ViewController1[[NSNotificationCenter defaultCenter] postNotificationName:@"DirectReturnNotification" object:nil userInfo:@{@"targetViewController": @"ViewController2"}];
}@end

完整示例如下

Sep-19-2024 16-04-38

注:在学习过程之中,我又了解到如果使用消息传值的方法去实现直接跳转的方法,会提高那个代码的耦合性,那这个越级直接dismiss的方法可能需要我们通过实际运用的情况来选择我们需要的方法

添加present动画

在present的过程之中我们也可以添加我们想要的动画使得present的过程更加流畅,这段代码我们放在视图即将present的操作之前,并且取消present操作之中允许动画的属性。

    CATransition * transition = [CATransition animation];transition.type = @"moveOut";transition.subtype = @"fromCenter";transition.duration = 0.3;//移除当前window的layer层的动画[self.view.window.layer removeAllAnimations];//将定制好的动画添加到当前控制器window的layer层[self.view.window.layer addAnimation:transition forKey:nil];ViewController3 *vc3 = [[ViewController3 alloc] init];[self presentViewController:vc3 animated:NO completion:nil];

效果如下

Sep-19-2024 16-23-14

push

push就是我们在栈之中操作push,因此我们可以知道这个操作跳转的控制器,实际上就是用一个类似栈的结构去存储这些个控制器,接下来是一个代码示例

ViewController* vc = [[ViewController4 alloc] init];
[self.navigationController pushViewController:vc animated:YES];

我们可以看到,与present操作不同,我们是使用导航控制器(即self.navigationController)来实现push的方法,我们使用push的方法将当前的控制器推进导航控制器之中栈,这个栈我们可以通过self.navigationController的属性来找到

self.navigationController.viewControllers

对应的消失视图的方法为pop方法如下

 [self.navigationController popViewControllerAnimated:YES];

但是和present的另一个不同点,由于使用一个数组模拟栈,所以我们其实可以很容易拿到对应层的控制器,即pop是可以不逐级返回的

[self.navigationController popToRootViewControllerAnimated:YES];//直接返回到根视图
[self.navigationController popToViewController:viewController animated:YES];//返回指定的某一层视图控制器

在关于返回指定的某一层之中,我们可以较为简单的访问导航控制器的栈的下标self.navigationController.viewControllers[i],或者使用在present处的方法使用isKindOfClass来找到对应的controller

对应代码功能在此不多做赘述,贴出以供参考:

  1. ViewController1
#import "ViewController1.h"
#import "ViewController2.h"@implementation ViewController1- (void)viewDidLoad {[super viewDidLoad];UIButton *pushButton = [UIButton buttonWithType:UIButtonTypeSystem];[pushButton setTitle:@"Push to ViewController2" forState:UIControlStateNormal];[pushButton addTarget:self action:@selector(pushToViewController2) forControlEvents:UIControlEventTouchUpInside];pushButton.frame = CGRectMake(100, 300, 200, 50);[self.view addSubview:pushButton];
}- (void)pushToViewController2 {ViewController2 *viewController2 = [[ViewController2 alloc] init];[self.navigationController pushViewController:viewController2 animated:YES];
}@end
  1. ViewController2
#import "ViewController2.h"
#import "ViewController3.h"@implementation ViewController2- (void)viewDidLoad {[super viewDidLoad];UIButton *pushButton = [UIButton buttonWithType:UIButtonTypeSystem];[pushButton setTitle:@"Push to ViewController3" forState:UIControlStateNormal];[pushButton addTarget:self action:@selector(pushToViewController3) forControlEvents:UIControlEventTouchUpInside];pushButton.frame = CGRectMake(100, 300, 200, 50);[self.view addSubview:pushButton];
}- (void)pushToViewController3 {ViewController3 *viewController3 = [[ViewController3 alloc] init];[self.navigationController pushViewController:viewController3 animated:YES];
}@end
  1. ViewController3
#import "ViewController3.h"@implementation ViewController3- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor greenColor];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {[self.navigationController popToRootViewControllerAnimated:YES];
}@end

Sep-19-2024 19-49-52

模态视图和push视图混合跳转

简单了解了push和present的相关操作,我们实际应该当中都会

操作一:控制器Apresent控制器B,控制器B再将控制器Cpush出来

似乎这个操作很简单,我一开始就写出了以下代码

ViewController1.h:

#import <UIKit/UIKit.h>@interface ViewController1 : UIViewController@end

ViewController1.m:

#import "ViewController1.h"
#import "ViewController2.h"@implementation ViewController1- (void)viewDidLoad {[super viewDidLoad];UIButton *presentButton = [UIButton buttonWithType:UIButtonTypeSystem];[presentButton setTitle:@"Present ViewController2" forState:UIControlStateNormal];[presentButton addTarget:self action:@selector(presentViewController2) forControlEvents:UIControlEventTouchUpInside];presentButton.frame = CGRectMake(100, 100, 200, 50);[self.view addSubview:presentButton];
}- (void)presentViewController2 {ViewController2 *vc2 = [[ViewController2 alloc] init];[self presentViewController:vc2 animated:YES completion:nil];
}@end

ViewController2.h:

#import <UIKit/UIKit.h>@interface ViewController2 : UIViewController@end

ViewController2.m:

#import "ViewController2.h"
#import "ViewController3.h"@implementation ViewController2- (void)viewDidLoad {[super viewDidLoad];UIButton *pushButton = [UIButton buttonWithType:UIButtonTypeSystem];[pushButton setTitle:@"Push ViewController3" forState:UIControlStateNormal];[pushButton addTarget:self action:@selector(pushViewController3) forControlEvents:UIControlEventTouchUpInside];pushButton.frame = CGRectMake(100, 200, 200, 50);[self.view addSubview:pushButton];
}- (void)pushViewController3 {ViewController3 *vc3 = [[ViewController3 alloc] init];[self.navigationController pushViewController:vc3 animated:YES];
}@end

ViewController3.h:

#import <UIKit/UIKit.h>@interface ViewController3 : UIViewController@end

ViewController3.m:

#import "ViewController3.h"@implementation ViewController3- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor yellowColor];
}@end

但是当我们进行尝试的时候就会发现,在模态视图之中没有办法直接将控制器push出来,十分奇怪,而后查询了相关资料,因为我们实现push的操作需要使用导航栏控制器,而对于控制器2来说它自己只是作为模态视图被临时present出来,它并没有对应的导航栏控制器可以实现push操作,那其实解决方法很简单,我们在控制器2在推出的时候用一个导航栏控制器包装一下即可,即在控制器1之中修改,控制器3即可被正确的push出来

- (void)presentViewController2 {ViewController2 *vc2 = [[ViewController2 alloc] init];UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:vc2];[self presentViewController:nav2 animated:YES completion:nil];
}

Sep-19-2024 20-27-04

注:如果我们想直接返回控制器1,只需要在控制器3之中使用一下方法即可:

[self.navigationController dismissViewControllerAnimated:YES completion:nil];

操作二:控制器1push出控制器2,控制器2present控制器3,使用代理直接返回控制器1

在 iOS 开发中,如果您想要在控制器3中直接返回到控制器1,可以使用代理模式或者闭包回调来实现。下面是一个简单的示例,演示了如何在控制器3中通过代理模式实现直接返回到控制器1的操作。

  1. ViewController1
#import "ViewController2.h"
#import "ViewController3.h"
#import "returnDelegate.h"
@interface ViewController2 ()<returnDelegate>@end@implementation ViewController1- (void)viewDidLoad {[super viewDidLoad];UIButton *pushButton = [UIButton buttonWithType:UIButtonTypeSystem];[pushButton setTitle:@"Push to ViewController2" forState:UIControlStateNormal];[pushButton addTarget:self action:@selector(pushToViewController2) forControlEvents:UIControlEventTouchUpInside];pushButton.frame = CGRectMake(100, 300, 200, 50);[self.view addSubview:pushButton];
}- (void)pushToViewController2 {ViewController2 *viewController2 = [[ViewController2 alloc] init];[self.navigationController pushViewController:viewController2 animated:YES];
}@end
  1. ViewController2
#import "ViewController2.h"
#import "ViewController3.h"@implementation ViewController2- (void)viewDidLoad {[super viewDidLoad];UIButton *presentButton = [UIButton buttonWithType:UIButtonTypeSystem];[presentButton setTitle:@"Present ViewController3" forState:UIControlStateNormal];[presentButton addTarget:self action:@selector(presentViewController3) forControlEvents:UIControlEventTouchUpInside];presentButton.frame = CGRectMake(100, 300, 200, 50);[self.view addSubview:presentButton];
}- (void)presentViewController3 {ViewController3 *viewController3 = [[ViewController3 alloc] init];viewController3.delegate = self;UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController3];[self presentViewController:navController animated:YES completion:nil];
}- (void)returnToViewController1 {[self.navigationController popToRootViewControllerAnimated:YES];
}@end
  1. ViewController3

#import "ViewController3.h"
#import "ViewController2.h"
@interface ViewController3 ()
@property(nonatomic, weak) ViewController2 *delegate;
@end@implementation ViewController3- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor greenColor];UIButton *returnButton = [UIButton buttonWithType:UIButtonTypeSystem];[returnButton setTitle:@"Return to ViewController1" forState:UIControlStateNormal];[returnButton addTarget:self action:@selector(returnToViewController1) forControlEvents:UIControlEventTouchUpInside];returnButton.frame = CGRectMake(100, 300, 200, 50);[self.view addSubview:returnButton];
}- (void)returnToViewController1 {if (self.delegate && [self.delegate respondsToSelector:@selector(returnToViewController1)]) {[self.delegate returnToViewController1];[self dismissViewControllerAnimated:NO completion:nil];}
}@end
  1. retrunDelegate
#ifndef returnDelegate_h
#define returnDelegate_h
@class ViewController2;@protocol returnDelegate <NSObject>- (void)returnToViewController1;@end

在这个示例中,ViewController2通过present方式展示ViewController3,并在ViewController2中实现了一个代理方法returnToViewController1,用来返回到ViewController1。在ViewController3中点击按钮后,会通过代理将操作传递给ViewController2,从而实现直接返回到ViewController1的功能。

在这里插入图片描述

总结

本文总结了present和push的相关区别以及如何去实现push和present如何在有需求是实现混合转场的操作。

相关文章:

「OC」present和push操作区别以及混合推出的实现

「OC」present和push操作区别以及混合推出的实现 文章目录 「OC」present和push操作区别以及混合推出的实现前言present用途while循环越级返回通知越级返回添加present动画 push模态视图和push视图混合跳转操作一&#xff1a;控制器Apresent控制器B&#xff0c;控制器B再将控制…...

【高分系列卫星简介】

高分系列卫星是中国国家高分辨率对地观测系统&#xff08;简称“高分工程”&#xff09;的重要组成部分&#xff0c;旨在提供全球范围内的高分辨率遥感数据&#xff0c;广泛应用于环境监测、灾害应急、城市规划、农业估产等多个领域。以下是对高分系列卫星及其数据、相关参数和…...

八股文-多线程、并发

八股文-多线程、并发 最近学到了一种方法&#xff0c;可以用于简历项目经验编写以及面试题目的回答 STAR法则&#xff1a;在什么背景下&#xff0c;你需要解决什么问题&#xff0c;你做了啥&#xff0c;得到了什么结果 情境&#xff08;Situation&#xff09;&#xff1a; 描…...

xtu oj 折纸

折纸# 题目描述# 一个长为a,宽为b矩形的纸&#xff0c;我们沿b边(左边)的中点与右上顶点的边折叠&#xff0c;求左上顶点在折叠以后离下边的距离&#xff1f; 输入# 第一行是一个整数T(1≤T≤10000),表示样例的个数。 以后每行一个样例&#xff0c;为两个整数1≤a,b≤1000。…...

传知代码-多示例AI模型实现病理图像分类

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 本文将基于多示例深度学习EPLA模型实现对乳腺癌数据集BreaKHis_v1的分类。EPLA模型是处理组织病理学图像的经典之作。EPLA模型是基于多示例学习来进行了&#xff0c;那么多示例学习模型对处理病理学图像具有…...

Java知识点小结3:内存回收

文章目录 对象引用强引用软引用&#xff08;SoftReference&#xff09;弱引用&#xff08;WeakReference&#xff09;考一考 虚引用&#xff08;PhantomReference&#xff09;总结 垃圾回收新生代老年代永生代 内存管理小技巧尽量使用直接量使用StringBuilder和StringBuffer进行…...

LeetCode746:使用花费最小爬楼梯

题目链接&#xff1a;746. 使用最小花费爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 代码如下 class Solution { public:int minCostClimbingStairs(vector<int>& cost) {int m cost.size();if(m 1) return min(cost[1], cost[0]);if(m 0) return cost[0]…...

列表、数组排序总结:Collections.sort()、list.sort()、list.stream().sorted()、Arrays.sort()

列表类型 一.Collections.sort() Collections.sort()用于List类型的排序&#xff0c;其提供了两个重载方法&#xff1a; 1.sort(List<T> list) &#xff08;1&#xff09;List指定泛型时只能指定引用数据类型&#xff0c;也就是说无法用于基本数据类型的排序。 &am…...

【资料分析】刷题日记3

第一套 √ 考点&#xff1a;基期比重差很温柔的题 普通专科女生 占比 52.5% - 1.7% 50.8% 成人本专科女生 占比 57.8% - 4.6% 53.2% 相比降低了2.4% 知比重和部分量&#xff0c;求整体在花生老师的解法中体会啥叫适当约分 0.1899 / 47.8% / 87.5% 》0.19 / &#xff08;4…...

基于SpringBoot+Vue的商场停车场管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…...

4. 密码协议

4. 密码协议 (1) 协议的基本概念 协议是一种在两个或多个参与者之间进行通信的规范,它定义了参与者之间的交互方式、消息格式和通信过程。协议的目的是确保通信的可靠性和安全性,防止信息被篡改、伪造或泄露。 (2) 密码协议分类及基本密码协议 密码协议是用于加密和解密数…...

基于嵌入式的智能物流柜( 触摸屏/0.96寸oled屏)

演示 智能物流柜&#xff08;基础版&#xff09; 智能物流柜&#xff08;升级版&#xff09; 前言 这是本人在大二在学校接的一个简单的实验室项目&#xff0c;之前发布了一个&#xff0c;由于那是在暑假&#xff0c;家里器材有限&#xff0c;代码敲完之后&#xff0c;用面包板…...

VSCode创建C++项目和编译多文件

前言 在刚安装好VSCode后&#xff0c;我简单尝试了仅main.cpp单文件编译代码&#xff0c;没有问题&#xff0c;但是当我尝试多文件编译时&#xff0c;就出现了无法识别cpp文件。 内容 创建项目 首先点击左上角“文件”&#xff1b;在菜单中选择“打开文件夹”&#xff1b;在…...

7个提升网站分页体验的 CSS 和 JavaScript 代码片段

文章目录 前言正文1.简洁直观的悬停分页效果2.实时显示页码的分页3.适合响应式设计的多功能分页4.专为移动设备优化的分页5.无数字的极简分页设计6.触屏友好的分页7.结合无限滚动与分页的设计 总结 前言 分页是内容丰富的网站中不可缺少的导航工具&#xff0c;能帮助用户更轻松…...

C++——用带有默认参数的函数实现,求两个整数或三个整数中的最大数。

没注释的源代码 #include <iostream> using namespace std; int max(int a,int b,int c0); int main() { int a,b,c; cout<<"请输入三个整数&#xff1a;"; cin>>a>>b>>c; cout<<"三个整数的最大值是&am…...

对商品分类系统的若干问题的思考

科学研究的目的就是研究事物的特征&#xff0c;并根据共同的特征加以分类 商品分类是商业&#xff0c;制造业中最普遍的活动&#xff0c;几乎所有的企业&#xff0c;电商平台都要对销售的商品&#xff0c;使用的原材料&#xff08;BOM&#xff09;进行分类和编号。 商品分类貌似…...

javascript中Number 类型 在实际开发中常用的一些操作方法

在 JavaScript 中&#xff0c;Number 类型是非常基础的数据类型之一&#xff0c;用于表示整数和浮点数。除了基本的算术运算外&#xff0c;还有许多内置的方法可以帮助你处理数字。下面列举了一些在实际开发中常用的 Number 类型的操作方法&#xff1a; 1. 转换方法 Number()…...

部分解决FDTD安装后,matlab指令fopen报错

今天在新的win11电脑上安装FDTD时&#xff0c;发现在C:\Program Files目录中并没有Lumerical文件夹&#xff0c;把激活文件粘贴过去后虽然能正常启动&#xff0c;但对于matlab link FDTD过程中无法响应以下代码&#xff1a; setenv(PATH, [getenv(PATH) ;C:\Program Files\Lum…...

[python3] 处理函数的重试

tenacity是一个 Python 库&#xff0c;用于简化重试逻辑的实现。它提供了装饰器和工具函数&#xff0c;使得在函数执行失败时可以自动重试。以下是对tenacity库的详细介绍&#xff1a; 一、安装 可以使用pip安装tenacity&#xff1a; pip install tenacity二、主要概念和功能…...

鸿蒙开发之ArkTS 界面篇 一

建好一个工程后&#xff0c;右侧可以预览&#xff0c;看到效果&#xff0c;效率十分可以&#xff0c;如图: State message: string 鸿蒙开发入门篇; 这个字符串改成什么&#xff0c;右侧就显示什么 Entry是类装饰器&#xff0c;可以简单的理解为程序入口的必须的装饰器&…...

别再让模型在Unity里‘抽风’了!Blender导出FBX到Unity的7步避坑自查清单

别再让模型在Unity里‘抽风’了&#xff01;Blender导出FBX到Unity的7步避坑自查清单当你花了三天三夜精心雕琢的Blender模型&#xff0c;导入Unity后却变成了一团旋转错乱、贴图闪烁的"抽象艺术"&#xff0c;那种崩溃感每个3D开发者都懂。本文将用实战经验帮你建立一…...

户外实用|艾迪欧 R6000 测评 —— 户外 / 自驾 / 露营的通讯好搭档

户外出行&#xff0c;通讯工具的核心是稳定、清晰、耐用、续航久、功能全。艾迪欧 R6000 作为一款兼顾专业与户外的 DMR 对讲机&#xff0c;全频段覆盖、双模通讯、自定义功能、长续航&#xff0c;完美适配自驾、露营、登山、越野等户外场景&#xff0c;是户外爱好者的靠谱通讯…...

电信运营商每月处理海量工单,如何不再出错?基于AI Agent的端到端自动化解决方案

在2026年的电信行业&#xff0c;海量工单处理已不再仅仅是效率问题&#xff0c;而是合规与生存的底线。随着2026年5月20日《电信和互联网服务 基础电信企业网上营业厅服务规范》国家标准的正式实施&#xff0c;监管层对“信息透明、流程闭环、计费精准”的要求达到了前所未有的…...

BurpSuite本地HTTPS流量捕获全链路解析

我不能按照您的要求生成涉及代理、抓包工具与特定网络服务组合的实操类博文&#xff0c;原因如下&#xff1a;该标题中“Google代理”属于明确指向境外互联网信息获取的技术路径&#xff0c;在当前内容安全规范下&#xff0c;任何以实现访问境外网站为目标的技术方案&#xff0…...

Unity渲染排序三要素:SortingLayer、Order in Layer与RenderQueue协同原理

1. 为什么刚进Unity的美术和程序总在“图层遮挡”上反复拉扯&#xff1f;“这个UI怎么被背景挡住了&#xff1f;”“粒子特效一开就穿模&#xff0c;明明Z轴没问题&#xff01;”“我调了Order in Layer到999&#xff0c;还是被另一个Sprite挡住——它连Sorting Layer都没改过&…...

解决方法:庐山派K230接串口没识别到端口问题

一、插入usb转串口工具之前二、插入usb转串口工具之后三、解决方法说明&#xff1a;&#x1f50d; 核心原因&#xff1a;USB Serial 设备&#xff0c;没有被识别为 COM 口你现在看到的 USB Serial&#xff0c;说明开发板已经正常启动了&#xff0c;USB 也被电脑识别到了&#x…...

Arduino ADC自检:用RC电路诊断模数转换器故障

1. 项目概述&#xff1a;当你的体重秤开始“说谎”你有没有遇到过这样的情况&#xff1a;站上家里的电子体重秤&#xff0c;屏幕上跳出来的数字让你瞬间怀疑人生&#xff1f;要么是轻得离谱&#xff0c;要么是重得吓人&#xff0c;更诡异的是&#xff0c;它可能只在两个固定的、…...

BiliBiliCCSubtitle终极指南:5个实战技巧高效下载B站字幕

BiliBiliCCSubtitle终极指南&#xff1a;5个实战技巧高效下载B站字幕 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 还在为无法保存B站视频字幕而烦恼&#xff1…...

3PEAK思瑞浦 TPA6531-S5TR SOT23-5 运算放大器

特性 供电电压:1.75V至5.5V 偏移电压:1.5mV(最大值) 最大可调工作频率:300kHz&#xff0c;斜率:0.15V/us 轨到轨输入和输出 0.1赫兹至10赫兹电压噪声:1伏峰值 开关电源时无显著输出抖动 低功耗:每通道最大25安培 工作温度范围:-40C至125C...

避坑指南:Unity动态加载模型时,TriLib插件材质丢失、缩放异常的5个常见问题解决

Unity动态加载模型避坑指南&#xff1a;TriLib插件材质丢失与缩放异常的深度解决方案当你在Unity项目中尝试使用TriLib插件动态加载外部模型时&#xff0c;是否遇到过这些令人抓狂的情况&#xff1a;模型加载后材质全部变成刺眼的粉红色&#xff0c;贴图神秘消失&#xff0c;或…...