【iOS】UICollectionView的基本使用

使用UITableView作为表格来展示数据完全没有问题,但仍有许多局限性,对于一些更加复杂的布局样式,就有些力不从心了

比如,UITableView只允许表格每一行只能显示一个cell,而不能在一行中显示多个cell,对于这种更为复杂的布局需求,UICollectionView可以提供更好的支持,有着更大的灵活性和扩展性,其主要优势有以下几点:

  • 支持横向 + 纵向两个方向的布局
  • 更加灵活的布局方式、动画
  • 可以动态对布局进行重设(切换layout)

目录

    • UICollectionView的基础使用
      • 显示UICollectionView
      • UICollectionViewLayout布局策略(UICollectionViewLayoutAttributes)
        • UICollectionViewFlowLayout流式布局
        • 九宫格布局
        • 更加灵活的流式布局
    • 参差瀑布流布局
      • 声明MyLayout类
      • 设置MyLayout相关属性
    • 圆环布局
    • 总结


UICollectionView的基础使用

作为升级版的UITableView,UICollectionView有许多与UITableView相似的点,可以通过对比UITableView总结来进行学习:

  • row —> item:由于一行可以展示多个视图,row不能准确表达
  • - (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;:注册cell类型,并设置重用ID
  • - (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;:cell复用,与UITableViewCell的注册机制一样,每次调用这个方法时,如果复用池中没有可复用的cell(cell为空),会根据重用ID自动创建一个新的cell并返回

显示UICollectionView

下面展示一个最基本的CollectionView


@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
@end- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.view.backgroundColor = [UIColor blueColor];//创建布局策略UICollectionViewFlowLayout* flowLayOut = [[UICollectionViewFlowLayout alloc] init];//第二个参数flowLayout用于生成UICollectionView的布局信息,后面会解释这个布局类UICollectionView* collectionView = [[UICollectionView alloc] initWithFrame: self.view.bounds collectionViewLayout: flowLayOut];collectionView.dataSource = self;//注册cell[collectionView registerClass: [UICollectionViewCell class] forCellWithReuseIdentifier: @"UICollectionViewCell"];[self.view addSubview: collectionView];
}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return 21;
}- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier: @"UICollectionViewCell" forIndexPath: indexPath];//cell的颜色cell.backgroundColor = [UIColor cyanColor];//cell默认是50X50的大小return cell;
}

请添加图片描述

UICollectionViewLayout布局策略(UICollectionViewLayoutAttributes)

请添加图片描述

layout管理多个attributes,一个cell就会对应一个布局信息attribute

UICollectionViewFlowLayout流式布局

作为一个生成布局信息(item的大小、位置、3D变换等)的抽象类,要实际使用需要继承,比如系统提供的继承于UICollectionViewLayout的一个流式布局类UICollectionViewFlowLayout,下面使用这个类来进行布局:

UICollectionViewFlowLayout* flowLayOut = [[UICollectionViewFlowLayout alloc] init];//设置布局方向
flowLayOut.scrollDirection = UICollectionViewScrollDirectionVertical;
flowLayOut.minimumLineSpacing = 10;  //行间距
flowLayOut.minimumInteritemSpacing = 10;  //列间距//设置每个item的尺寸
flowLayOut.itemSize = CGSizeMake(self.view.frame.size.width / 2 - 5, 300);
//    flowLayOut.itemSize = CGSizeMake(self.view.frame.size.width / 2 - 50, 300);

请添加图片描述

scrollDirection属性

该类的scrollDirection属性用于设置布局的方向,支持的布局方向枚举如下:
请添加图片描述

若将枚举值改为UICollectionViewScrollDirectionHorizontal,将会这样排列:
在这里插入图片描述

前者当一行满时,另起一行;后者当一列满时,另起一列

minimumInteritemSpacing最小列间距属性

系统通过minimumInteritemSpacing属性计算一行可以放多少个item,当发现放不下计算好的item个数时,为了撑满所在行,此值就会变大,比如:

flowLayOut.itemSize = CGSizeMake(self.view.frame.size.width / 2 - 12, 300);

请添加图片描述

minimumLineSpacing最小行间距同理

九宫格布局

UITableView类似,UICollectionView不仅内部也有一套复用机制来对注册的cell进行复用,而且也是通过dataSourcedelegate协议来进行数据填充相关属性设置的:

@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.view.backgroundColor = [UIColor blueColor];UICollectionViewFlowLayout* flowLayOut = [[UICollectionViewFlowLayout alloc] init];flowLayOut.scrollDirection = UICollectionViewScrollDirectionVertical;CGFloat side = (self.view.bounds.size.width - 12) / 3;flowLayOut.minimumLineSpacing = 6;flowLayOut.minimumInteritemSpacing = 6;flowLayOut.itemSize = CGSizeMake(side, side);UICollectionView* collectionView = [[UICollectionView alloc] initWithFrame: self.view.bounds collectionViewLayout: flowLayOut];collectionView.dataSource = self;collectionView.delegate = self;[collectionView registerClass: [UICollectionViewCell class] forCellWithReuseIdentifier: @"UICollectionViewCell"];[self.view addSubview: collectionView];
}//设置分区数
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 1;
}//设置每个分区的
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return 10;
}//每条item上cell的UI展现
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier: @"UICollectionViewCell" forIndexPath: indexPath];//随机颜色cell.backgroundColor = [UIColor colorWithRed: arc4random() % 255 / 255.0 green: arc4random() % 255 / 255.0 blue: arc4random() % 255 / 255.0 alpha: 1.0];return cell;
}

请添加图片描述

更加灵活的流式布局
//实现delegate,自定义任何位置上cell的样式
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {if (indexPath.item % 2) {return CGSizeMake((self.view.bounds.size.width - 12) / 3, (self.view.bounds.size.width - 12) / 3);} else {return CGSizeMake((self.view.bounds.size.width - 12) / 6, (self.view.bounds.size.width - 12) / 6);}
}

请添加图片描述

参差瀑布流布局

在很多应用程序中都有瀑布流效果,即分成两列或者多列进行数据的展示,每条数据itemcell的高度也随数据多少不同而显示得参差不齐

使用系统提供的原生UICollectionViewFlowLayout类进行布局设置很难实现这样的效果,开发者可以自定义一个它的子类来实现瀑布流式的效果

流布局又称瀑布流布局,是一种比较流行的网页布局模式,视觉效果多表现为参差不齐的多栏布局。

声明MyLayout类

创建一个布局类MyLayout,使其继承于UICollectionViewFlowLayout,并新增一个属性itemCount用于设置要布局的item的数量:

MyLayout.h

@interface MyLayout : UICollectionViewFlowLayout
@property (nonatomic, assign)NSInteger itemCount;
@end

设置MyLayout相关属性

请添加图片描述

UICollectionViewLayout类提供了prepareLayout来做布局前的准备,这个时机会调用此方法,可以在其中设置布局配置数组:

MyLayout.m

@implementation MyLayout {//自定义的布局配置数组,保存每个cell的布局信息attributeNSMutableArray* _attributeArray;
}//布局前的准备会调用这个方法
- (void)prepareLayout {_attributeArray = [[NSMutableArray alloc] init];[super prepareLayout];//为方便演示,设置为静态的2列//计算每一个Item的宽度//sectionInset表示item距离section四个方向的内边距 UIEdgeInsetsMake(top, left, bottom, right)CGFloat WIDTH = ([UIScreen mainScreen].bounds.size.width - self.sectionInset.left - self.sectionInset.right - self.minimumInteritemSpacing) / 2;//创建数组保存每一列的高度(实际是总高度),这样就可以在布局时始终将下一个Item放在最短的列下面CGFloat colHeight[2] = {self.sectionInset.top, self.sectionInset.bottom};//遍历每一个Item来设置布局for (int i = 0; i < self.itemCount; ++i) {//每个Item在CollectionView中的位置NSIndexPath* indexPath = [NSIndexPath indexPathForItem: i inSection: 0];//通过indexPath创建一个布局属性类UICollectionViewLayoutAttributes* attris = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath: indexPath];//随机一个高度,在77~200之间CGFloat height = arc4random() % 123 + 77;//那一列高度小,则放到哪一列下面int indexCol = 0;  //标记短的列if (colHeight[0] < colHeight[1]) {//将新的Item高度加入到短的一列colHeight[0] = colHeight[0] + height + self.minimumLineSpacing;indexCol = 0;} else {colHeight[1] = colHeight[1] + height + self.minimumLineSpacing;indexCol = 1;}//设置Item的位置attris.frame = CGRectMake(self.sectionInset.left + (self.minimumInteritemSpacing + WIDTH) * indexCol, colHeight[indexCol] - height - self.minimumLineSpacing, WIDTH, height);[_attributeArray addObject: attris];}//给itemSize赋值,确保滑动范围在正确区间,这里是通过将所有的Item高度平均化计算出来的//(以最高的列为标准)if (colHeight[0] > colHeight[1]) {self.itemSize = CGSizeMake(WIDTH, (colHeight[0] - self.sectionInset.top) * 2 / self.itemCount - self.minimumLineSpacing);} else {self.itemSize = CGSizeMake(WIDTH, (colHeight[1] - self.sectionInset.top) * 2 / self.itemCount - self.minimumLineSpacing);}
}//此系统提供的方法会返回设置好的布局数组
- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect: (CGRect)rect {return _attributeArray;
}@end
  • 先声明一个_attributeArray数组存放每个item的布局信息
  • 在UICollectionView进行布局时,首先会调用其Layout布局类的prepareLayout方法,在这个方法中可以进行每个item布局属性的相关计算操作
  • 具体每个item的布局属性实际是保存在UICollectionViewLayoutAttributes类对象中的,其中包括sizeframe等信息,并与每个item一一对应
  • prepareLayout方法准备好所有item的Attributes布局属性后,以数组的形式调用layoutAttributesForElementsInRect:方法来返回给UICollectionView进行界面的布局

ViewController.m引入MyLayout文件并使用这个类:

#import "MyLayout.h"- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor blueColor];//使用自定义的layout类MyLayout* myLayout = [[MyLayout alloc] init];myLayout.itemCount = 21;UICollectionView* collectionView = [[UICollectionView alloc] initWithFrame: self.view.bounds collectionViewLayout: myLayout];collectionView.dataSource = self;collectionView.delegate = self;[self.view addSubview: collectionView];[collectionView registerClass: [UICollectionViewCell class] forCellWithReuseIdentifier: @"MyUICollectionView"];
}- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 1;
}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return 21;
}- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {UICollectionViewCell* myCell = [collectionView dequeueReusableCellWithReuseIdentifier: @"MyUICollectionView" forIndexPath: indexPath];myCell.backgroundColor = [UIColor colorWithRed: arc4random() % 255 / 255.0 green: arc4random() % 255 / 255.0 blue: arc4random() % 255 / 255.0 alpha: 1.0];return myCell;
}

运行结果:

参差瀑布流布局

圆环布局

通过上面的代码我们可知,UICollectionView的布局原理是采用Layout类进行每个item布局信息的配置的,具体的配置信息由UICollectionViewLayoutAttributes存储。

明白了这个机制后,我们可以发挥想象实现更加炫酷复杂的布局效果。

与参差瀑布式布局一样,这里附上圆环布局代码:

CircleLayout.h

@interface CircleLayout : UICollectionViewFlowLayout
@property (nonatomic, assign)NSInteger itemCount;
@end

CircleLayout.m

@implementation CircleLayout {NSMutableArray* _attributeArray;
}- (void)prepareLayout {[super prepareLayout];//获取item的个数self.itemCount = (int)[self.collectionView numberOfItemsInSection: 0];_attributeArray = [[NSMutableArray alloc] init];//先设定大圆的半径,取长和宽的最小值CGFloat radius = MIN(self.collectionView.frame.size.width, self.collectionView.frame.size.height) / 2;//计算圆心位置CGPoint center = CGPointMake(self.collectionView.frame.size.width / 2, self.collectionView.frame.size.height / 2);//每个item大小为50*50,即半径为25for (int i = 0; i < self.itemCount; ++i) {NSIndexPath* indexPath = [NSIndexPath indexPathForItem: i inSection: 0];UICollectionViewLayoutAttributes* attris = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath: indexPath];//设置item大小attris.size = CGSizeMake(50, 50);//计算每个item中心坐标(圆心位置)float x = center.x + cosf(2 * M_PI / self.itemCount * i) * (radius - 25);float y = center.y + sinf(2 * M_PI / self.itemCount * i) * (radius - 25);attris.center = CGPointMake(x, y);[_attributeArray addObject: attris];}
}//设置内容区域的大小
//作用同赋值contentSize属性一样,返回一个CollectionView可以滑动的范围尺寸
- (CGSize)collectionViewContentSize {return self.collectionView.frame.size;
}- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {return _attributeArray;
}
@end

ViewController.m

- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor blueColor];//使用自定义的layout类
//    MyLayout* myLayout = [[MyLayout alloc] init];
//    myLayout.itemCount = 21;CircleLayout* circleLayout = [[CircleLayout alloc] init];UICollectionView* collectionView = [[UICollectionView alloc] initWithFrame: self.view.bounds collectionViewLayout: circleLayout];collectionView.backgroundColor = [UIColor blackColor];collectionView.dataSource = self;collectionView.delegate = self;[self.view addSubview: collectionView];//    [collectionView registerClass: [UICollectionViewCell class] forCellWithReuseIdentifier: @"MyUICollectionView"];[collectionView registerClass: [UICollectionViewCell class] forCellWithReuseIdentifier: @"CircleUICollectionView"];
}- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 1;
}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return 11;
}- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
//    UICollectionViewCell* myCell = [collectionView dequeueReusableCellWithReuseIdentifier: @"MyUICollectionView" forIndexPath: indexPath];UICollectionViewCell* circleCell = [collectionView dequeueReusableCellWithReuseIdentifier: @"CircleUICollectionView" forIndexPath: indexPath];circleCell.layer.masksToBounds = YES;circleCell.layer.cornerRadius = 25;circleCell.backgroundColor = [UIColor colorWithRed: arc4random() % 255 / 255.0 green: arc4random() % 255 / 255.0 blue: arc4random() % 255 / 255.0 alpha: 1.0];return circleCell;
}@end

运行结果:
请添加图片描述

总结

UICollectionView其实算是特殊Flow布局的UITableView,但简单的列表仍可以使用UITableView

UICollectionView最大的优势就是通过自定义Layout,实现cell的布局,整体的思路就是:通过一些几何计算,设置好每个item的布局位置和大小

在之后的学习中,编者也将参考这片文章:一篇较为详细的 UICollectionView 使用方法总结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构_C++语言描述_高教出版社

contents 前言一、绪论1.1 数据分析结构存储算法计算1.1.1 逻辑结构1.1.2 存储结构1.1.3 算法实现 1.2 数据类型1.3 算法方法 二、线性表2.1 线性表的逻辑结构2.2 线性表的存储结构2.2.1 顺序存储结构2.2.2 链式存储结构 2.3 线性表的操作算法2.3.1 顺序表的操作算法2.3.2 链表…

【c++函数重载】

文章目录 一. 命名空间二 .全缺省参数和半缺省参数三 . 函数重载 一. 命名空间 1.不指定域&#xff1a;先在局部找&#xff0c;再全局。 2. 指定域&#xff1a;到指定的命名空间去找。 3. 当把指定命名空间放开时&#xff0c;即using namespace std&#xff1b;例如放开标准c库…

5.2 基于深度学习和先验状态的实时指纹室内定位

文献来源 Nabati M, Ghorashi S A. A real-time fingerprint-based indoor positioning using deep learning and preceding states[J]. Expert Systems with Applications, 2023, 213: 118889.&#xff08;5.2_基于指纹的实时室内定位&#xff0c;使用深度学习和前一状态&…

让uniapp小程序支持多色图标icon:iconfont-tools-cli

前景&#xff1a; uniapp开发小程序项目时&#xff0c;对于iconfont多色图标无法直接支持&#xff1b;若将多色icon下载引入项目则必须关注包体&#xff0c;若将图标放在oss或者哪里管理&#xff0c;加载又是一个问题&#xff0c;因此大多采用iconfont-tools工具&#xff0c;但…

【php】php去除excel导入时的空格

背景 PHPExcel_1.8.0导入excel&#xff0c;遇到trim无法处理的空格。 解决方案 $excelVal preg_replace(“/(\s| | |\xc2\xa0)/”, ‘’, $excelVal); 完整代码 thinkphp5代码 function readExcel($file) {require_once EXTEND_PATH . PHPExcel_1.8.0/Classes/PHPExcel.p…

靶场实战(18):OSCP备考之VulnHub MY CMSMS

打靶思路 资产发现 主机发现服务发现漏洞发现&#xff08;获取权限&#xff09; 80端口/HTTP服务 组件漏洞URL漏洞3306端口/MySQL服务 组件漏洞口令漏洞80端口/HTTP服务 URL漏洞URL漏洞提升权限 www-data用户 sudosuidcron内核提权信息收集armour用户 sudo 1、资产发现 1.1…

考研C语言刷编程题篇之分支循环结构基础篇(一)

目录 第一题 第二题 方法一&#xff1a;要循环两次&#xff0c;一次求阶乘&#xff0c;一次求和。 注意&#xff1a;在求和时&#xff0c;如果不将sum每次求和的初始值置为1&#xff0c;那么求和就会重复。 方法二&#xff1a; 第三题 方法一&#xff1a;用数组遍历的思想…

【大数据处理技术实践】期末考查题目:集群搭建、合并文件与数据统计可视化

集群搭建、合并文件与数据统计可视化 实验目的任务一&#xff1a;任务二&#xff1a; 实验平台实验内容及步骤任务一&#xff1a;搭建具有3个DataNode节点的HDFS集群集群环境配置克隆的方式创建 Slave 节点修改主机名编辑 hosts 文件生成密钥免认证登录修改 hadoop 的配置文件编…

Java并发编程: 并发编程中的ExecutionException异常

一、什么是ExecutionException 在并发编程中在执行java.util.concurrent.Future实现类的get方法时&#xff0c;需要捕获java.util.concurrent.ExecutionException这个异常。Future.get()方法通常是要获取任务的执行结果&#xff0c;当执行任务的过程中抛出了异常&#xff0c;就…

ThinkPad T14/T15/P14s/P15s gen2电脑原厂Win10系统镜像 恢复笔记本出厂时预装自带OEM系统

lenovo联想原装出厂Windows10系统&#xff0c;适用型号&#xff1a; ThinkPad T14 Gen 2&#xff0c;ThinPad T15 Gen 2&#xff0c;ThinkPad P14s Gen 2&#xff0c;ThinkPad P15s Gen 2 &#xff08;20W1,20W5,20VY,20W7,20W0,20W4,20VX,20W6&#xff09; 链接&#xff1…

Redis在Windows10中安装和配置

1.首先去下载Redis 这里不给出下载地址&#xff0c;自己可以用去搜索一下地址 下载 下载完成后解压到D盘redis下&#xff0c;本人用的是3.2.100 D:\Redis\Redis-x64-3.2.100 2.解压完成后需要设置环境变量&#xff0c;这里新建一个系统环境变量中path 中添加一个文件所…

WCP知识分享平台的容器化部署

1. 什么是WCP? WCP是一个知识管理、分享平台,支持针对文档(包括pdf,word,excel等)进行实时解析、索引、查询。 通过WCP知识分享平台进行知识信息的收集、维护、分享。 通过知识创建、知识更新、知识检索、知识分享、知识评价、知识统计等功能进行知识生命周期管理。 wcp官…

第04章_IDEA的安装与使用(上)(认识,卸载与安装,JDK相关设置,详细设置,工程与模块管理,代码模板的使用)

文章目录 第04章_IDEA的安装与使用&#xff08;上&#xff09;本章专题与脉络1. 认识IntelliJ IDEA1.1 JetBrains 公司介绍1.2 IntelliJ IDEA 介绍1.3 IDEA的主要优势&#xff1a;(vs Eclipse)1.4 IDEA 的下载 2. 卸载与安装2.1 卸载过程2.2 安装前的准备2.3 安装过程2.4 注册2…

【小笔记】算法训练基础超参数调优思路

【学而不思则罔&#xff0c;思维不学则怠】 本文总结一下常见的一些算法训练超参数调优思路&#xff08;陆续总结更新&#xff09;&#xff0c;包括&#xff1a; batchsize学习率epochsdropout&#xff08;待添加&#xff09; Batch_size 2023.9.29 简单来说&#xff0c;较…

学习笔记之——3D Gaussian SLAM,SplaTAM配置(Linux)与源码解读

SplaTAM全称是《SplaTAM: Splat, Track & Map 3D Gaussians for Dense RGB-D SLAM》&#xff0c;是第一个&#xff08;也是目前唯一一个&#xff09;开源的用3D Gaussian Splatting&#xff08;3DGS&#xff09;来做SLAM的工作。 在下面博客中&#xff0c;已经对3DGS进行了…

基于springboot+vue的宠物领养系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 背景及意…

C++参悟:正则表达式库regex

正则表达式库regex 一、概述二、快速上手Demo1. 查找字符串2. 匹配字符串3. 替换字符串 三、类关系梳理1. 主类1. basic_regex 2. 算法1. regex_match2. regex_search3. regex_replace 3. 迭代器4. 异常5. 特征6. 常量1. syntax_option_type2. match_flag_type3. error_type 一…

Unity animator动画倒放的方法

在Unity中&#xff0c; 我们有时候不仅需要animator正放的效果&#xff0c;也需要倒放的效果。但我们在实际制作动画的时候可以只制作一个正放的动画&#xff0c;然后通过代码控制倒放。 实现方法其实很简单&#xff0c;只需要把animator动画的speed设置为-1即为倒放&#xff…

科技护航 智慧军休打通医养结合最后一公里

“小度小度&#xff0c;请帮我打电话给医生。” “好的&#xff0c;马上呼叫植物路军休所医生。” 2023年9月25日&#xff0c;常年独居、家住广西南宁市植物路军休所的军休干部程老&#xff0c;半夜突发疾病&#xff0c;让他想不到的是&#xff0c;这个常年伴他左右的“小度”…

Centos 8 安装 Elasticsearch

简介&#xff1a;CentOS 8是一个基于Red Hat Enterprise Linux&#xff08;RHEL&#xff09;源代码构建的开源操作系统。它是一款稳定、可靠、安全的服务器操作系统&#xff0c;适合用于企业级应用和服务的部署。CentOS 8采用了最新的Linux内核和软件包管理系统&#xff0c;提供…