「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如何在有需求是实现混合转场的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145664.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

影视会员充值api?接口对接需要做哪些准备工作?

影视会员充值 API 接口对接主要有以下步骤&#xff1a; 1.前期准备 明确自身需求&#xff1a;确定你希望通过 API 接口实现的功能&#xff0c;例如支持哪些影视平台的会员充值、是否需要获取会员信息、是否需要订单查询功能等。选择合适的 API 提供商&#xff1a;官方视频平台…

中国电子学会202312青少年软件编程(Python)等级考试试卷(三级)真题

2023年12月青少年软件编程Python等级考试(三级)真题试卷 题目总数:38 总分数:100 一、选择题 第 1 题 单选题 一个非零的二进制正整数,在其末尾添加两个“0”,则该新数将是原数的?( ) A.10倍 B.2倍 C.4倍 D.8倍 第 2 题 单选题 2023年亚运会将在杭…

分步指南:如何使用 ChatGPT 撰写文献综述

撰写文献综述对于研究人员和学生来说,往往是一项既耗时又复杂的任务。这一过程不仅要求对所选主题的现有研究进行全面的了解和掌握,还需要学术严谨性。然而,随着像 ChatGPT 这样的高级语言模型的广泛应用,撰写文献综述的过程变得更加高效和简化。通过合理利用 ChatGPT,研究…

跨国公司决策的影响与中国IT产业的应对

跨国公司在华研发中心的调整是一个复杂的现象&#xff0c;它可能受到多种因素的影响&#xff0c;包括全球经济环境的变化、成本考量、战略重心的转移以及地缘政治因素等。IBM中国研发中心的撤出可能会对中国IT行业造成短期的就业压力&#xff0c;加速人才流动&#xff0c;并促使…

【LeetCode】每日一题 2024_9_20 统计特殊整数(数位 DP)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;统计特殊整数 代码与解题思路 func countSpecialNumbers(n int) int { // 今天的题目是数位 DP&#xff0c;我不会做&#xff0c;所以现场学习了一下灵神的数位 DP 模版s : strconv.Itoa…

轻松打造:用Python实现手机与电脑间的简易消息系统

展示&#x1f3a5; 观看视频&#xff1a;&#x1f440;&#xff0c;这是之前完成的一个项目&#xff0c;但今天我们的重点不是这个哦。 告别往昔&#xff0c;启航新篇章 现象&#x1f31f; 智能互动&#xff1a;&#x1f4f1; 我们每天都在享受与智能设备的互动&#xff0c;…

哪个快?用300万个图斑测试ArcGIS Pro的成对叠加与经典叠加

​​​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 在使用ArcGIS Pro的过程中&#xff0c;很多朋友发现&#xff0c;Pro有个成对叠加工具集。很多…

图片转pdf在线怎么转?分享5种简单好用的转换方法

在日常工作和学习中&#xff0c;我们经常会遇到需要将图片转换为PDF格式的情况。无论是为了保存文档方便查阅&#xff0c;还是为了提升文件的专业性和安全性&#xff0c;掌握图片转PDF的技巧都显得尤为重要。下面给大家分享5种转换方法&#xff0c;简单高效&#xff0c;一起来了…

b2b2c商城系统好用么 多用户商城系统四大盈利模式

商淘云B2B2C商城系统能帮助企业快速搭建企业自己的多用户商城系统&#xff0c;它提供了多种功能&#xff0c;如多商家管理、订单处理、支付模块集成等&#xff0c;适合各种规模的企业。用户界面友好&#xff0c;且支持定制化&#xff0c;能满足不同业务需求。 多用户商城有四大…

HTTP协议详解以及常见的状态码

HTTP协议的定义&#xff1a; HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种建立在TCP&#xff08;传输控制协议&#xff09;之上的无状态连接协议。它是互联网的基础协议之一&#xff0c;用于客户端与服务器之间的通信。HTTP规定…

【C++二叉树】105.从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树 - 力扣&#xff08;LeetCode&#xff09; 根据前序遍历和中序遍历构建二叉树 前序遍历访问方式&#xff1a;根-左子树-右子树 中序遍历访问方式&#xff1a;左子树-根-右子树 思路分析&#xff1a; 前序中序可以构建一颗二叉树&#xf…

微信视频号的视频怎么下载提取?详细操作流程来了!

微信视频号是腾讯为用户提供的娱乐学习的短视频平台&#xff0c;用户可通过视频号中的内容进行查看浏览&#xff0c;但不少人因视频号本身不具备创作灵感&#xff0c;故此需要下载提取高清视频号的内容。 视频号下载视频 视频下载是用户想通过软件或者插件进行保存微信视频号…

文献阅读(81)FACT

题目&#xff1a;FACT: FFN-Attention Co-optimized Transformer Architecture with Eager Correlation Prediction时间&#xff1a;2023会议&#xff1a;ISCA研究机构&#xff1a;清华 主要贡献 算法优化&#xff1a;提出了Eager Prediction (EP)&#xff0c;预测softmax前重…

马踏棋盘c++

马踏棋盘c 题目回溯问题模型特征模型 代码 题目 马踏棋盘算法&#xff0c;即骑士周游问题。将马放在国际象棋的 88 棋盘的某个方格中&#xff0c;马按走棋规则(马走日字)进行移动。每个方格只进入一次&#xff0c;走遍棋盘上全部 64 个方格。 回溯问题模型 特征 解组织成树…

MySQL高阶1867-最大数量高于平均水平的订单

目录 题目 准备数据 分析数据 题目 您正在运行一个电子商务网站&#xff0c;该网站正在寻找不平衡的订单。不平衡订单的订单最大数量严格大于每个订单&#xff08;包括订单本身&#xff09;的平均数量。 订单的平均数量计算为&#xff08;订单中所有产品的总数量&#xff…

数商:数字时代的新认知

在数字时代&#xff0c;“数商” 概念兴起&#xff0c;代表着人们在该时代应具备的新认知与能力。 数商即数字商数&#xff0c;指个体在数字时代认知、理解、运用数字技术和数据的能力&#xff0c;以及进行有效决策、创新和合作的素养。其内涵包括数字认知能力、数据素养、数字…

计算机毕业论文题目之基于Web技术B/S结构的新生管理系统包含报道,寝室宿舍,缴费学费,数据统计分析汇总等功能的源代码下载

为了满足功能需求&#xff0c;我们将设计并实现一个基于Web技术的B/S架构下的新生管理系统。本系统旨在通过前端与后端分离的设计模式&#xff0c;为用户提供简洁、高效的交互体验&#xff0c;并确保数据的安全性和系统的可扩展性。下面将从系统架构、功能模块以及技术选型三个…

【练习13】字符串中找连续最长的数字串

链接&#xff1a;字符串中找出连续最长的数字串_牛客题霸_牛客网 (nowcoder.com) 原理分析&#xff1a;模拟双指针 为什么用到BufferedReader 和 InputStreamReader组合输入字符&#xff1f; 因为BufferedReader 内部维护了一个字符缓冲区&#xff0c;调用readLine()方法时&…

全网最全的软件测试八股文

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行&#xff0c;可以实现跨平台&#xff0c;客户端零维护&#xff0c;维护成本低&#xff0c;但是个…

基于SpringBoot+Vue的剧本杀管理系统

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