【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的布局信息attribute
    NSMutableArray* _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

  1. 先声明一个_attributeArray数组存放每个item的布局信息
  2. 在UICollectionView进行布局时,首先会调用其Layout布局类的prepareLayout方法,在这个方法中可以进行每个item布局属性的相关计算操作
  3. 具体每个item的布局属性实际是保存在UICollectionViewLayoutAttributes类对象中的,其中包括sizeframe等信息,并与每个item一一对应
  4. 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,即半径为25
    for (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 使用方法总结

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IN操作符

目录 IN NOT IN Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 IN IN 指的是根据一个指定的范围进行数据查询 1.查询出员工编号是 7369、7566、7788、9999 的员工信息 利用前面学的知识,得出: SQL> set linesize 250 SQL>…

​第14节-高质量简历写作求职通关-在线测试

在线测试主要包括性格测试、综合能力测试、技能测试三类 性格测试 性格测试主要用于考察个人与工岗位的匹配程度 考察内容包含性格、能力、动机、价值观等&#xff0c;考察形式一般为给出相应的工作场景&#xff0c;让你选择最喜欢或者最不喜欢的答案 技能考试 这类测试一般是针…

Windows云服务器如何配置多用户登录?(Windows 2012)华为云官方文档与视频地址

Windows云服务器如何配置多用户登录&#xff1f;&#xff08;Windows 2012&#xff09;_弹性云服务器 ECS_故障排除_多用户登录_华为云 打开任务栏左下角的“服务器管理器”&#xff0c;在左侧列表中选中“本地服务器” 然后将右侧“远程桌面”功能的选项修改为“启用”&#x…

LeetCode 13.罗马数字转整数(python版)

需求 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#xff0c; 罗马数字 2 写做 II &#xff0c;即为两个并列的 1 。12 写做 XII &#xff0c;即为 X …

如何对遗留 C++ 代码进行现代化改造?

C 在过去的十年中进步很大&#xff0c;以至于有些人把它看作是一种完全不同的语言&#xff0c;而不是“老旧的遗留 C”。尽管现代 C 依然保留了与原来的准则和基本语法&#xff0c;但这些更新和进步对 C 语言和标准库意义重大。 不过&#xff0c;也不是每个人都在使用最新版本…

Unity 工厂方法模式(实例详解)

文章目录 在Unity中&#xff0c;工厂方法模式是一种创建对象的常用设计模式&#xff0c;它提供了一个接口用于创建对象&#xff0c;而具体的产品类是由子类决定的。这样可以将对象的创建过程与使用过程解耦&#xff0c;使得代码更加灵活和可扩展。 工厂模式的主要优点如下&…

快速排序(三)——hoare法

目录 ​一.前言 二.快速排序 hoare排法​ 三.结语 一.前言 本文给大家带来的是快速排序&#xff0c;快速排序是一种很强大的排序方法&#xff0c;相信大家在学习完后一定会有所收获。 码字不易&#xff0c;希望大家多多支持我呀&#xff01;&#xff08;三连&#xff0b;关…

PADS自动导出Gerber文件 —— 双面板

视频地址&#xff1a;PADS_2层PCB板(双面板) 快速出GERBER光绘文件实战视频教程_哔哩哔哩_bilibili 像pads做封装不用做阻焊层&#xff0c;因为在出GERBER文件的时候调用了焊盘&#xff0c;并在焊盘的基础上增加了几个mil来做阻焊层。 出Gerber文件之前一定要先铺铜并且检查无错…

双指针算法专题

前言 双指针算法入门&#xff0c;干就完了 下面的题目都是来自灵神的基础算法精讲&#xff0c;有思路不清晰的地方&#xff0c;可以去看讲解。 灵茶山艾府的个人空间-灵茶山艾府个人主页-哔哩哔哩视频 (bilibili.com) 相向双指针 1.两数之和 题目链接&#xff1a;167. 两数之…

清华大模型Chatglm2-6B的微调方法和微调模型使用方式(非常仔细,值得借鉴)

一、下载chatglm2-6b的项目代码和模型 1、下载chatglm2-6b的项目 方法一、chatglm2-6b的项目下载地址&#xff1a; https://github.com/THUDM/ChatGLM2-6B方法二、百度网盘提取chatglm2-6b的项目&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1BEwUhiIJlB4SJrGw7N…

力扣:474. 一和零(动态规划)(01背包)

题目&#xff1a; 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#xff0c;集合 x 是集合 y 的 子集 。 示例 1&#xff1a; 输入&#…

MacOS受欢迎的数据库开发工具 Navicat Premium 15 中文版

Navicat Premium 15 Mac是一款数据库管理工具&#xff0c;提供了一个全面的解决方案&#xff0c;用于连接、管理和维护各种数据库系统。以下是Navicat Premium 15 Mac的一些主要功能和特点&#xff1a; 软件下载&#xff1a;Navicat Premium 15 中文版下载 多平台支持&#xff…

【UE5】第一次尝试项目转插件(Plugin)的时候,无法编译

VS显示100条左右的错误&#xff0c;UE热编译也不能通过。原因可能是[名字.Build.cs]文件的错误&#xff0c;缺少一些内容&#xff0c;比如说如果要写UserWidget类&#xff0c;那么就要在 ]名字.Build.cs] 中加入如下内容&#xff1a; public class beibaoxitong : ModuleRules …

140:vue+leaflet加载here地图(v2软件多种形式)

第140个 点击查看专栏目录 本示例介绍如何在vue+leaflet中添加HERE地图(v2版本的软件),并且含多种的表现形式。包括地图类型,文字标记的设置、语言的选择、PPI的设定。 v3版本和v2版本有很大的区别,关键是引用方法上,请参考文章尾部的API链接。 直接复制下面的 vue+leaf…

哈尔滨游“出圈”,上市公司谁在冰雪经济掘金?

今年冬季&#xff0c;冰雪游热度不减&#xff0c;哈尔滨成为最大赢家。 仅在元旦假期&#xff0c;根据携程数据显示&#xff0c;黑龙江元旦假期订单量同比增长490%&#xff0c;其中&#xff0c;哈尔滨元旦旅游订单同比增长631%。 受哈尔滨旅游市场出圈影响的出圈&#xff0c;…

仿真机器人-深度学习CV和激光雷达感知(项目2)day5【作业1与答案1】

文章目录 前言作业1答案1 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;本文内容是我为复试准备的第二个项目 &#x1f4ab;欢迎大家的关注&#xff0c;我的博客主要关注于考研408以及AIoT的内容 &#x1f31f; 预置知识…

Science Robotics: 意大利IIT仿生软体机器人实验室研制具有自适应行为的软体生长机器人

FiloBot通过模仿攀爬植物的生长方式——通过在顶端增加材料来构建身体&#xff0c;实现在难以预测和复杂的环境中的导航。这种设计理念的核心在于能够适应多种地形并克服障碍&#xff0c;特别适用于密集森林或杂乱区域这样的非结构化环境。机器人使用添加制造技术&#xff08;特…

【 CSS 】基础 2

“生活就像骑自行车&#xff0c;想要保持平衡&#xff0c;就得不断前行。” - 阿尔伯特爱因斯坦 CSS 基础 2 1. emmet 语法 1.1 简介 Emmet语法的前身是 Zen coding&#xff0c;它使用缩写&#xff0c;来提高 HTML / CSS 的编写速度&#xff0c; VSCode 内部已经集成该语法。…

GIS项目实战06:超详细Node.js安装及系统环境配置

简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境&#xff0c;基于 Google 的 V8 引擎&#xff0c;V8 引擎执行 Javascript 的速度非常快&#xff0c;性能…

超全的测试类型详解,再也不怕面试答不出来了!

在软件测试工作过程中或者在面试过程中经常会被问到一些看起来简单但是总是有些回答不上的问题&#xff0c;比如你说说“黑盒测试和白盒测试的区别&#xff1f;”&#xff0c;“你们公司做灰度测试么&#xff1f;", ”α测试和β测试有什么不一样&#xff1f;“&#xff0…