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

「iOS」自定义Modal转场——抽屉视图的实现

「iOS」自定义Modal转场——抽屉视图的实现

文章目录

  • 「iOS」自定义Modal转场——抽屉视图的实现
    • 前言
    • 错误尝试
    • 自定义Modal转场
      • 实现流程
      • 自定义动画类
      • UIPresentationController
    • 成果展示
    • 参考文章

前言

在仿写网易云的过程之中,看到学长之前仿写时实现的抽屉视图,不明觉厉,于是在仿写完3Gshared之后选择沉淀一下,来对网易云设置界面之中的抽屉视图以及圆角cell进行仿写以及学习,本来是想将这两个内容一起发为一篇博客的,但是在实现的过程之中发现,就单单让控制器从左边弹出就费了一番功夫,因此将如何实现自定义模态视图的推出,先整理为一篇笔记为先。

我是想要实现网易云那样的抽屉视图推出,即推出界面之后,右侧空白处显示的是原先控制器右侧的内容,我看到网上大部分使用transform进行平移,这样就使得空白处显示的原先视图控制器的左侧内容,于是就绕了很多弯子。

错误尝试

对于抽屉视图,我开始是想要使用UINavigationController实现(即pop和push的方法)从左到右推出和从右到左淡出的效果,即从JCThird跳转至JCSecond之中

//前一个视图推出控制器
-(void)pushToJCSecond {CATransition *transition = [CATransition animation];transition.duration = 0.3;transition.type = kCATransitionPush;transition.subtype = kCATransitionFromLeft; [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; JCSecond *second = [[JCSecond alloc] init];second.view.backgroundColor = [UIColor clearColor]; [self.navigationController pushViewController:second animated:YES];
}//后一个控制器的内容
(void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.view.backgroundColor = [UIColor clearColor];UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(backButtonTapped)];CGFloat width = [UIScreen mainScreen].bounds.size.width; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width * 5 / 6, [UIScreen mainScreen].bounds.size.height)];view.backgroundColor = [UIColor redColor];[self.view addSubview:view];self.navigationItem.leftBarButtonItem = backButton;
}

但是发现,当视图顺利的从我的设想的动画之中弹出的时候,出现了问题,我即使将控制器的背景右侧六分之一设置为透明,但是透明一侧透露的最多多只是UITabBarController的一角,情况如下,是在是解决不了这个问题,于是选择放弃。初步推出是与推出视图的负责视图即父视图有关。如有解决方法请,请看到的大佬不吝赐教。

Jul-29-2024 10-46-50

自定义Modal转场

那既然push/pop的方法不能做到,我就想着使用present/dismiss模态视图的方式,能不能实现呢?我们在使用present/dismiss的时候,一般来说能够控制present/dismiss出来控制器的高低,能在空白处看到上一个视图的部分内容。通过学习了解,我知道了和模态视图推出相关的一个属性,是在控制器之中的modalPresentationStyle,这个属性可以控制模态视图推出的时的形态,比如UIModalPresentationFullScreen可以让模态视图充满整一个屏幕。但可惜的是在可选的style并不能直接实现让视图从左到右推出的功能,于是我就接着了解到了如何自定义Modal转场的转场动画。

这个过程之中需要的内容其实自我感觉称得上复杂,大致有五个内容:

1.UIViewControllerAnimatedTransitioning 一个协议,这个接口负责切换的具体内容,也即“切换中发生了什么动画”,动画实现只需要实现其两个代理方法就行

2.UIViewControllerTransitioningDelegate 一个协议,需要控制器切换的时候系统会向实现了这个接口的对象询问是否需要使用自定义的切换效果,也就是选择自定义的动画

3.UIPresentationController 控制控制器跳转的类,是 iOS8 新增的一个 API,用来控制 controller 之间的跳转特效可以用它实现自定义的弹窗,以及弹出的控制器的大小都可以根据这个来进行设置

4.modalPresentationStyle 这是UIViewController 的一个属性,就是字面意思,modal的样式,自定义的话,需要设置为Custom

5.transitioningDelegate 就是谁去实现 UIViewControllerTransitioningDelegate 这个协议的代理方法,一般用一个专门的类管理

实现流程

一开始看起来东西好像很多,我们可以慢慢来,一点一点的进行学习,首先我们要知道我们自定义一个Modal转场需要什么东西,一个遵循协议UIViewControllerAnimatedTransitioning自定义的动画类来实现从左到右弹出的动画,以及从右到左收回的动画,我们还需要重写UIPresentationController来控制弹出控制器的大小范围,以及添加半透明的黑色视图实现相关效果,这个可能听起来有点难理解,不过到后面就都了解了

自定义动画类

@protocol UIViewControllerAnimatedTransitioning <NSObject>// This is used for percent driven interactive transitions, as well as for
// container controllers that have companion animations that might need to
// synchronize with the main animation.
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
// This method can only be a no-op if the transition is interactive and not a percentDriven interactive transition.
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;@end

这是我们点进UIViewControllerAnimatedTransitioning可以看到的内容,可以看到一共可以实现两个方法,第一个方法我们通过返回值不难看出与时间相关,进而猜测这个方法其实与动画时间相关。

我们在这两个方法之中都能够看到一个协议名字,名为UIViewControllerContextTransitioning,这个名字含有Context协议其实就是转场动画的核心,遵循这个协议的transitionContext 即包含了转场动画的上下文(即前一个控制器和后一个控制器)。

@protocol UIViewControllerContextTransitioning <NSObject>
//转场动画的容器
@property(nonatomic, readonly) UIView *containerView;@property(nonatomic, readonly, getter=isAnimated) BOOL animated;// The next two values can change if the animating transition is interruptible.
@property(nonatomic, readonly, getter=isInteractive) BOOL interactive; // This indicates whether the transition is currently interactive.
@property(nonatomic, readonly) BOOL transitionWasCancelled;@property(nonatomic, readonly) UIModalPresentationStyle presentationStyle;- (void)completeTransition:(BOOL)didComplete;//通过两个to和from的枚举量,能在上下文之中获得相应的控制器
- (nullable __kindof UIViewController *)viewControllerForKey:(UITransitionContextViewControllerKey)key;//获取上下文视图大小
- (CGRect)initialFrameForViewController:(UIViewController *)vc;
- (CGRect)finalFrameForViewController:(UIViewController *)vc;
@end

了解了这些我们就可以先写一个,一个自定义的动画类了,首先这个类的父类是NSOject,且需要遵循 UIViewControllerAnimatedTransitioning协议,头文件如下:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN@interface slide : NSObject <UIViewControllerAnimatedTransitioning>@property (nonatomic, assign) BOOL isPresentation;@endNS_ASSUME_NONNULL_END

有细心的读者就会发现了,这个头文件之中还定义了布尔的属性,这个属性有什么用呢,前面我们说过,这个协议就只有两种方法,一个关于动画时间,一个关于模态视图的上下文以及动画,由于没有对present/dismiss进行明确的划分,所以我们要在属性之中添加一个属性来判断是对视图进行present/dismiss

接下来就是.m文件 —— 事先声明JCSecond以及JCThird为两个控制器的名称

#import "slide.h"@implementation slide- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {return 0.3;
}- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {UIView *containerView = [transitionContext containerView];//to是指变化的下文,from是指变化的上文UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];UIView *toView = toViewController.view;UIView *fromView = fromViewController.view;//用于获取源视图控制器(fromViewController)在转场开始前的位置信息。CGRect initialFrame = [transitionContext initialFrameForViewController:fromViewController];//用于获取目标视图控制器(toViewController)在转场结束后的位置信息。CGRect finalFrame = [transitionContext finalFrameForViewController:toViewController];//如果决定是将视图present则将toView加入containerView之中,并将 toView.frame先置于视图最后位置的左边,这样当动画变化的时候就会实现从左到右滑滑出if (self.isPresentation) {toView.frame = CGRectOffset(finalFrame, -finalFrame.size.width, 0);[containerView addSubview:toView];}UIView *animatingView = self.isPresentation ? toView : fromView;//确保拿到的都是JCSecond这个控制器以便进行动画//如果为dismiss那么就将最后的位置置于JCSecond的左边CGRect targetFrame = self.isPresentation ? finalFrame : CGRectOffset(initialFrame, -initialFrame.size.width, 0);[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{animatingView.frame = targetFrame;} completion:^(BOOL finished) {if (!self.isPresentation) {[fromView removeFromSuperview];//如果为dismiss就将JCSecond全部移除}[transitionContext completeTransition:YES];}];
}@end

在这个.m文件的第二个方法之中,我们看到了很多,之前我们在UIViewControllerContextTransitioning之中看到的东西,首先是获得上下文的控制器,但是注意一点presentdismiss的上下文并不相同,也就是说在present之中,toView是指JCSecond,fromVIew是指JCThird,在dismiss之中toVIew指的是JCSecond,fromView指的是JCThird

实现了自定义类之中我们就要,控制器之中的JCThird,去告诉编译器我们自己实现了一个动画,并将其运用至了present/dismiss的模态视图变化之中,我们就要先让该视图控制器实现协议UIViewControllerTransitioningDelegate之中的方法了,这个协议之中的方法就是告诉编译器我们想要使用何种动画方式进行’push/dismiss’。引入我们刚刚写的自定义动画类slide,告诉编译器需要用slide这个动画实例进行变化,以下就是JCThird的代码

- (void)pushToJCSecond {JCSecond *second = [[JCSecond alloc] init];second.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"back3.jpeg"]];//记得将modal改为自定义second.modalPresentationStyle = UIModalPresentationCustom;//实现协议的代理对象second.transitioningDelegate = self;[self presentViewController:second animated:YES completion:nil];
}
//管理present动画的
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {slide *animationController = [[slide alloc] init];animationController.isPresentation = YES;return animationController;
}
//管理dismiss动画的
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {slide *animationController = [[slide alloc] init];animationController.isPresentation = NO;return animationController;
}

我们运行一下试试看:

Jul-29-2024 15-45-28

不难发现,有点像了是不是,但是好像还是缺了什么,就是右边空白视图需要从亮到灰,而不是和弹出来的抽屉视图的亮度相同,笔者先前试过在viewWillDisappear之中加入一个半透明的灰色视图,结果发现由于覆盖的半透明视图是覆盖在JCThird之中,本身的UITabBarController并不会发生覆盖,而且present出来的视图控制器,界面仍然占据整个屏幕,这对于后面添加手势去dismiss视图也是一个难度。于是根据相关知识,我发现UIPresentationController似乎能够实现我想要完成的效果。

image-20240729155936704

JCSecond占据了整个屏幕

UIPresentationController

当我们使用presnt方法的时候控制器的presentationController就会提前创建好了,它负责管理视图控制器之间的呈现(presentation)和解散(dismissal)过程。

  1. presentationTransitionWillBegin

    • 作用:在呈现过渡即将开始时调用。
    • 用法:在此方法中执行呈现过渡的准备工作,如设置背景视图、添加自定义动画等。
  2. presentationTransitionDidEnd:

    • 作用:在呈现过渡结束时调用。
    • 用法:在此方法中执行呈现过渡完成后的清理工作,如处理用户交互、设置最终状态等。
  3. dismissalTransitionWillBegin

    • 作用:在解散过渡即将开始时调用。
    • 用法:在此方法中执行解散过渡的准备工作,如添加解散动画效果、隐藏视图等。
  4. dismissalTransitionDidEnd:

    • 作用:在解散过渡结束时调用。
    • 用法:在此方法中执行解散过渡完成后的清理工作,如移除视图、恢复状态等。
  5. frameOfPresentedViewInContainerView

    • 作用:返回呈现视图在容器视图中的位置和大小。
    • 用法:用于指定呈现视图在容器视图中的布局,可以自定义呈现视图的位置和大小。

我们可以根据重写视图控制器之中这些类似的方法一样,自己自定义 UIPresentationController 的行为已实现自己的需求。

OK了解完了原理,那我们就开始重写方法吧

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface present : UIPresentationController@endNS_ASSUME_NONNULL_END
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
#import "present.h"@implementation present
- (CGRect)frameOfPresentedViewInContainerView {CGFloat width = self.containerView.bounds.size.width * 5 / 6;return CGRectMake(0, 0, width, self.containerView.bounds.size.height);
}- (void)presentationTransitionWillBegin {UIView *dimmingView = [[UIView alloc] initWithFrame:self.containerView.bounds];dimmingView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];dimmingView.alpha = 0.0;dimmingView.tag = 1001;[self.containerView addSubview:dimmingView];[UIView animateWithDuration:0.3 animations:^{dimmingView.alpha = 1.0;}];UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];[dimmingView addGestureRecognizer:tapGesture];
}- (void)tap:(UITapGestureRecognizer *)gesture {[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}- (void)dismissalTransitionWillBegin {UIView *dimmingView = [self.containerView viewWithTag:1001];[UIView animateWithDuration:0.3 animations:^{dimmingView.alpha = 0.0;} completion:^(BOOL finished) {[dimmingView removeFromSuperview];}];
}
@end

我重写了frameOfPresentedViewInContainerView presentationTransitionWillBegin 以及 dismissalTransitionWillBegin这三个方法,其中frameOfPresentedViewInContainerView 就是限制了JCSecond的范围宽度为六分之五。

image-20240729164147075

presentationTransitionWillBegin 是在视图被present之前添加了一个黑色半透明的背景颜色,而在视图被present到屏幕上的时候,做一个动画渐变将半透明的黑色背景颜色逐渐显示(即alpha从0到1的过程),然后就是手势的添加,我们将其添加至背景视图的dimmingView,由于我们前面frameOfPresentedViewInContainerView 设定了JCSecond的具体大小,所以dimmingView会被JCSecond覆盖,所以只有我们点击到灰色的背景部分,这个抽屉视图才会执行手势的内容

dismissalTransitionWillBegin其实内容大同小异,只是将背景视图通过动画取消了而已,然后在动画结束的时候将背景视图移除,没有其他的内容。

成果展示

完整内容如下:

Jul-29-2024 16-42-53

好了我们这样终于完成了我们想要的抽屉视图,没想到一个看似简单的内容,自己学习以及整理笔记整理了快有两天之多,果然还是学习的内容太少了,没想到实现这个简单的内容还需要了解这么多东西,果然学习之路还是茫茫啊😭

参考文章

自定义Modal转场-模仿push & pop

iOS 自定义转场动画浅谈

你真的了解iOS中控制器的present和dismiss吗?

UIViewControllerAnimatedTransitioning

相关文章:

「iOS」自定义Modal转场——抽屉视图的实现

「iOS」自定义Modal转场——抽屉视图的实现 文章目录 「iOS」自定义Modal转场——抽屉视图的实现前言错误尝试自定义Modal转场实现流程自定义动画类UIPresentationController 成果展示参考文章 前言 在仿写网易云的过程之中&#xff0c;看到学长之前仿写时实现的抽屉视图&…...

【数据结构】顺序结构实现:特殊完全二叉树(堆)+堆排序

二叉树 一.二叉树的顺序结构二.堆的概念及结构三.堆的实现1.堆的结构2.堆的初始化、销毁、打印、判空3.堆中的值交换4.堆顶元素5.堆向上调整算法&#xff1a;实现小堆的插入6.堆向下调整算法&#xff1a;实现小堆的删除7.堆的创建1.堆向上调整算法&#xff1a;建堆建堆的时间复…...

【c++学习技术栈】

c学习技术栈 基础c基础组件中间件框架devops性能目标岗位 基础 计算机网络数据结构与算法操作系统linux c 基础组件 池式组件&#xff1a;线程池&#xff0c;内存池&#xff0c;db数据库连接池原子&#xff0c;无锁队列&#xff0c;ringbuffer&#xff0c;定时器。日志&…...

swift 自定义DatePacker

import Foundationenum AppDatePickerStyle {case KDatePickerDate //年月日case KDatePickerTime //年月日时分case kDatePickerMonth // 年月case KDatePickerSecond //秒}class AppDatePicker: UIView {private let jk_rootView UIApplication.shared.keyWindow!pri…...

MySQL事务,锁,MVCC总结

mysql中最重要的就是事务&#xff0c;其四大特性让我们维持了数据的平衡&#xff0c;一致。那么事务究竟是什么&#xff0c;与什么相关&#xff0c;他的使用步骤&#xff0c;以及使用过程中我们会遇到什么问题呢&#xff1f;下面我们一起学习交流! 1.MySQL的存储引擎&#xff…...

24/8/7 算法笔记 支持向量机回归问题天猫双十一

import numpy as np from sklearn.svm import SVR import matplotlib.pyplot as plt X np.linspace(0,2*np.pi,50).reshape(-1,1) y np.sin(X) plt.scatter(X,y) 建模 线性核函数 svr SVR(kernel linear) svr.fit(X,y.ravel())#变成一维y_ svr.predict(X) plt.scatter(…...

win7系统利用定时启动+脚本实现MySQL文件自动备份

前言 最近接到项目&#xff0c;数据量不大但对运行数据的安全性要求极高&#xff0c;为避免因不可抗拒因素导致的数据丢失&#xff0c;选择机械硬盘作为数据存储盘&#xff0c;并使用脚本方式对文件进行备份 一、脚本 下面为自动备份文件的 脚本&#xff0c;可根据自身情况进…...

基于Java多线程处理数据

基于Java多线程处理数据 背景代码实现 背景 在日常工作中&#xff0c;有一个同步企微客户-学员关系接口的定时任务在执行中随着数据量的不断增长&#xff0c;定时任务的执行结束时间也出现了当天执行不完的情况&#xff0c;影响到了正常业务的运行。基于这种情况&#xff0c;在…...

日常知识点之遇到问题结构体按位构造协议时和期望不一致,研究记录一下

遇到一个问题&#xff0c;在做业务的时候&#xff0c;涉及到协议相关&#xff0c;按位进行设计&#xff0c;用结构体来模拟协议时&#xff0c;发现内存存储和实际目的不一致&#xff0c;知道是大小端以及计算机底层存储逻辑相关&#xff0c;所以研究了一下。 1&#xff1a;简单…...

spring mvc 文件下载

在web中下载的方式大多基于servlet&#xff0c;在web.xml中配置下载路径&#xff0c;这里再介绍json(转成base64字符串)和blob的使用方式 servlet WEB-INF/web.xml <!--url映射--> <servlet-mapping><servlet-name>DowloadServlet</servlet-name>&l…...

Qt WebEngine基于WebEngineScript注入js脚本

在之前的文章中&#xff0c;我们介绍了Qt WebEngine注入js的用法&#xff0c;及runJavaScript()的用法&#xff0c;该方法主要是用在页面加载完成后&#xff0c;为了和网页做一些交互时使用。有时候需要监听网页加载完成的一些状态或信息&#xff0c;则需要网页加载前注入js来实…...

案例分享-国外UI设计界面赏析

国外UI设计倾向于简洁的布局和清晰的排版&#xff0c;减少视觉干扰&#xff0c;提升用户体验。通过合理的色彩搭配和图标设计&#xff0c;营造舒适愉悦的使用氛围。 设计师不拘泥于传统框架&#xff0c;勇于尝试新元素和理念&#xff0c;使界面独特有趣。同时&#xff0c;强调以…...

用PyTorch 从零开始构建 BitNet 1.58bit

我们手动实现BitNet的编写&#xff0c;并进行的一系列小实验证实&#xff0c;看看1.58bit 模型是否与全精度的大型语言模型相媲美&#xff01; 什么是量化以及为什么需要它&#xff1f; 量化是用更少的比特数表示浮点数的过程。当两个数字使用不同的比特数进行量化时&#xf…...

信创安全 | 新一代内网安全方案—零信任沙盒

在当今数字化时代&#xff0c;访问安全和数据安全成为企业面临的重要挑战。传统的边界防御已经无法满足日益复杂的内网办公环境&#xff0c;层出不穷的攻击手段已经让市场单一的防御手段黔驴技穷。当企业面临越来越复杂的网络威胁和数据泄密风险时&#xff0c;更需要一种综合的…...

Redis的回收策略(淘汰策略)

volatile-lru &#xff1a;从已设置过期时间的数据集&#xff08; server.db[i].expires &#xff09;中挑选最近最少使用的数据淘汰 volatile-ttl &#xff1a; 从已设置过期时间的数据集&#xff08; server.db[i].expires &#xff09; 中挑选将要过期的数据淘汰 volatile…...

Electron-builder 打包

项目比较简单&#xff0c;仅使用了 Electron 原生js 安装 electron-builder npm install electron-builder --dev配置 package.json 中的打包命令 {"script":{// ..."dev": "electron .","pack": "electron-builder"} }添…...

笔试练习day3

目录 BC149 简写单词题目解析代码 dd爱框框题目解析解析代码方法一暴力解法方法二同向双指针(滑动窗口) 除2!题目解析解法模拟贪心堆 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978;&#x1…...

企业想要将大模型技术应用到企业管理中需具备什么条件?

#企业 #企业管理 #大模型 企业想要将大模型技术应用到企业管理中&#xff0c;需要考虑以下几个关键条件&#xff1a; 1.明确的需求定位&#xff1a;企业应首先诊断自身的业务场景、数据、算法、基础设施预算以及战略等能力&#xff0c;明确大模型能够为企业带来的具体赋…...

go 事件机制(观察者设计模式)

背景&#xff1a; 公司目前有个业务&#xff0c;收到数据后&#xff0c;要分发给所有的客户端或者是业务模块&#xff0c;类似消息通知这样的需求&#xff0c;自然而然就想到了事件&#xff0c;观察者比较简单就自己实现以下&#xff0c;确保最小功能使用支持即可&#xff0c;其…...

RISC-V竞赛|第二届 RISC-V 软件移植及优化锦标赛报名正式开始!

目录 赛事背景 赛道方向 适配夺旗赛 优化竞速赛 比赛赛题&#xff08;总奖金池8万元&#xff01;&#xff09; &#x1f525;竞速赛 - OceanBase 移植与优化 比赛赛程&#xff08;暂定&#xff09; 赛事说明 「赛事背景」 为了推动 RISC-V 软件生态更快地发展&#xff0…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

Xcode 16 集成 cocoapods 报错

基于 Xcode 16 新建工程项目&#xff0c;集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...