【iOS】CollectionView、瀑布流式和圆环布局

news2024/11/27 0:42:10

使用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

  • 先声明一个_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,即半径为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 使用方法总结

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

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

相关文章

智慧工地解决方案及案例:PPT全文26页,附下载

关键词&#xff1a;智慧工地解决方案&#xff0c;智慧工地建设&#xff0c;智慧工地整体架构&#xff0c;数字化工地&#xff0c;智慧工程 一、智慧工地建设对传统建筑业的影响 1、提高了施工效率和质量&#xff1a;智慧工地建设采用了先进的信息技术和管理方法&#xff0c;可…

【C++】vector容器接口要点的补充

接口缩容 在VS编译器的模式下&#xff0c;类似于erase和insert接口的函数通常会进行缩容&#xff0c;因此&#xff0c;insert和erase行参中的迭代器可能会失效。下图中以erase为例&#xff1a; 代码如下&#xff1a; #include <iostream> #include <vector> #inclu…

前端面试题-html5新增特性有哪些

HTML html5新增特性有哪些 1.新增了语义化标签 标签用法header定义文档或区块的页眉&#xff0c;通常包含标题&#xff0c;导航和其他有关信息nav定义导航链接的容器&#xff0c;用于包裹网站的导航部分section定义文档的一个独立节或区块&#xff0c;用于组织相关的内容art…

【C++】用wxWidgets实现多文档窗体程序

一、基本步骤和示例代码 在wxWidgets中&#xff0c;要实现多文档窗体程序&#xff0c;通常会使用wxMDIParentFrame和wxMDIChildFrame类来创建一种标准的MDI&#xff08;多文档接口&#xff09;应用。以下是基本步骤和示例代码&#xff0c;演示如何使用wxWidgets创建多文档界面…

Deepin_Ubuntu_查看树形目录结构(tree)

Linux系统&#xff08;Deepin、Ubuntu&#xff09;中&#xff0c;可以使用tree命令来查看树形目录结构&#xff0c;下面是一些示例&#xff1a; 查看当前目录的树形结构&#xff1a; tree查看指定目录的树形结构&#xff0c;例如/etc/X11/fonts目录&#xff1a; tree /etc/X…

Cortex-M3/M4内核NVIC及HAL库函数详解(2):HAL库中断底层函数实现

0 工具准备 Keil uVision5 Cortex M3权威指南&#xff08;中文&#xff09; Cortex M3与M4权威指南 stm32f407的HAL库工程 STM32F4xx中文参考手册 1 HAL库中断底层函数实现 打开stm32f407的HAL库工程&#xff0c;可以在CMSIS->Include->core_cm4.h内找到有关NVIC寄存器设…

为什么使用物理、数学等工具不能实现对人类智能的模拟

物理和数学是研究自然界和抽象概念的工具&#xff0c;它们为我们提供了理论和方法来解决问题。在实现类人的智能方面&#xff0c;物理和数学可以应用于以下几个方面&#xff1a; 1、计算机科学和算法 数学中的逻辑、统计学和优化理论等可以用于开发智能算法和机器学习模型。这些…

【趣味题-03】20240120猴子吃桃( 从大到小insert ,列表元素互减)

背景需求&#xff1a; 猴子摘桃的题目 解决&#xff1a; 猴子吃桃 倍数问题 作者&#xff1a;阿夏 时间&#xff1a;2024年1月20日猴子吃桃问题-1 猴子第一天摘了许多桃子&#xff0c;第一天吃了一半&#xff0c;&#xff1b;第二天又吃了一半&#xff0c; 后面每天都是这样吃…

NLP论文阅读记录 - 2022 | WOS 04.基于 XAI 的强化学习方法,用于社交物联网内容的文本摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作三.本文方法3.1 总结为两阶段学习3.1.1 基础系统 3.2 重构文本摘要 四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 XAI-Base…

vue3 项目中 arguments 对象获取失败问题

问题 在 vue3 项目中 获取到的 arguments 对象与传入实参不符&#xff0c;打印出函数中的 arguments 对象显示如下&#xff1a; 原因 作者仔细回看代码才发现&#xff0c;自己一直用的是 vue3 的组合式写法&#xff0c;函数都是箭头函数&#xff0c;而箭头函数不存在 argumen…

GoZero微服务个人探究之路(七)添加中间件、自定义中间件

说在前面 官方已经自己实现了很多中间件&#xff0c;我们可以方便的直接使用&#xff0c;不用重复造轮子了 开启方式可以看官方文档 中间件 | go-zero Documentation 实现自定义的中间件 在业务逻辑中&#xff0c;我们需要实现自定义功能的中间件 ------这里我们以实现跨源…

【jQuery入门】链式编程、修改css、类操作和className的区别

文章目录 前言一、链式编程二、修改css2.1 获取css的值2.2 设置单个css属性2.3 设置类样式添加类移除类切换类 三、类操作与className的区别总结 前言 jQuery是一个流行的JavaScript库&#xff0c;广泛用于简化DOM操作和处理事件。在jQuery中&#xff0c;链式编程是一种强大的…

VisualSVN Server实战

文章目录 一、实战概述二、实战步骤&#xff08;一&#xff09;下载VisualSVN Server&#xff08;二&#xff09;安装VisualSVN Server&#xff08;三&#xff09;使用VisualSVN Server1、新建仓库&#xff08;1&#xff09;新建Repository&#xff08;2&#xff09;选择仓库类…

CentOS 7安装Java并配置环境

一、安装Java环境 1、检查系统是否安装Java [rootlocalhost ~]# java -version 2、更新系统软件包 [rootlocalhost ~]# yum update #遇到[y/n],选择y并回车&#xff0c;耐心等待下载完毕&#xff0c;之后系统会自动检验更新的软件包遇到 /var/run/yum.pid 已被锁定 /var/…

Microchip Studio修改工程名

打开工程后&#xff0c;右键选择重命名 右键工程重命名 关闭后回到工程下的文件夹 再次打开工程软件会显示加载失败&#xff0c;此时是找不到路径了 菜单栏打开工程 选择修改文件夹名字的路径下的cproj文件 然后点击关闭&#xff0c;会显示保存新的atsln文件&#xff0c;此时将…

web渗透安全学习笔记:2、HTML基础知识

目录 前言 HTML的标题 段落链接与插入图片 HTML元素 HTML属性 HTML头部 HTML与CSS HTML与JavaScript 表格与列表 HTML区块 布局 HTML表单 HTML与数据库 音频与视频 HTML事件 前言 HTML的标题 <!DOCTYPE html> <html> <head> <meta chars…

VMware workstation安装FreeBSD14.0虚拟机并配置网络

VMware workstation安装FreeBSD14.0虚拟机并配置网络 FreeBSD是类UNIX操作系统&#xff0c;FreeBSD带有多个软件包&#xff0c;并覆盖了广阔的应用领域&#xff0c;且都是免费和易于安装的。该文档适用于在VMware workstation平台安装FreeBSD14.0虚拟机。 1.安装准备 1.1安装…

事件驱动架构

请求驱动 服务注册&#xff0c;服务发现&#xff0c;虽然调用地址隐藏了&#xff0c;但是调用stub必须相同。 rpc通信&#xff0c;远程调用。 生产者和消费者要有相同的stub存根。 消费者和生产者的调用接口是耦合的。 事件驱动 核心&#xff1a;上下游不进行通信 中间通过M…

【Go】rune和byte类型的认识与使用

【Go】rune和byte类型的认识与使用 大家好 我是寸铁&#x1f44a; 总结了一篇rune和byte类型的认识与使用的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; byte和rune类型定义 byte,占用1个字节&#xff0c;共8个比特位&#xff0c;所以它实际上和uint8没什么本质区别,它表示…

qt学习:应用程序设置菜单栏+实战 打开文件菜单栏

目录 步骤如下 第一步&#xff0c;ui界面&#xff0c;双击菜单栏可以改菜单栏的内容 第二步&#xff0c;修改菜单栏 第三步&#xff0c;设置好的action拖到菜单栏 第四步&#xff0c;triggered槽函数实现 在qt中&#xff0c;如果想要使用菜单栏功能&#xff0c;那么界面的基…