iOS开发-聊天emoji表情与自定义动图表情左右滑动控件
iOS开发-聊天emoji表情与自定义动图表情左右滑动控件
之前开发中遇到需要实现聊天emoji表情与自定义动图表情左右滑动控件。使用UICollectionView实现。
一、效果图

二、实现代码
UICollectionView是一种类似于UITableView但又比UITableView功能更强大、更灵活的视图,这是源于它将UICollectionView对cell的布局交给了UICollectionViewLayout,而且允许用户自定义layout来进行布局。
2.1 UICollectionView初始化
INEmotionView.h
@interface INEmotionView : UIView@property (nonatomic, weak) id delegate;@property (nonatomic, strong) INEmotionFlowLayout *flowLayout;@property (nonatomic, strong) UICollectionView *collectionView;@property (nonatomic, strong) UIPageControl *pageControl;- (id)initWithFrame:(CGRect)frame;@end
INEmotionView.m
#import "INEmotionView.h"
#import "UIColor+Addition.h"static CGFloat kCollectionHeight = 260;@implementation INEmotionView- (id)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {self.backgroundColor = [UIColor colorWithHexString:@"efeff4"];self.flowLayout =[[INEmotionFlowLayout alloc] init];self.flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;self.collectionView = [[UICollectionView alloc]initWithFrame:frame collectionViewLayout:self.flowLayout];self.collectionView.backgroundColor = [UIColor clearColor];self.collectionView.scrollEnabled = YES;self.collectionView.pagingEnabled = YES;self.collectionView.showsVerticalScrollIndicator = NO;self.collectionView.showsHorizontalScrollIndicator = NO;self.collectionView.userInteractionEnabled = YES;self.collectionView.exclusiveTouch = YES;[self addSubview:self.collectionView];self.pageControl = [[UIPageControl alloc]initWithFrame:CGRectZero];self.pageControl.backgroundColor = [UIColor clearColor];self.pageControl.currentPage = 0;self.pageControl.numberOfPages = 0;self.pageControl.currentPageIndicatorTintColor = [UIColor redColor];self.pageControl.pageIndicatorTintColor = [UIColor greenColor];[self addSubview:self.pageControl];}return self;
}- (id)init {return [self initWithFrame:CGRectZero];
}- (void)layoutSubviews {[super layoutSubviews];self.collectionView.frame = CGRectMake(0.0, (CGRectGetHeight(self.bounds) - kCollectionHeight)/2, CGRectGetWidth(self.bounds), kCollectionHeight);self.pageControl.frame = CGRectMake(0.0, CGRectGetMaxY(self.collectionView.frame), CGRectGetWidth(self.bounds), 50);
}- (void)setDelegate:(id)delegate {_delegate = delegate;self.collectionView.delegate = delegate;self.collectionView.dataSource = delegate;
}@end
2.2 UICollectionView实现控件
emoji表情与自定义动图表情左右切换,需要根据拆分多个section,UICollectionView的datasource
我这里使用的是5个分组,每个分组的数量如下。
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 5;
}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {NSInteger sectionNumber = 60;switch (section) {case 0:sectionNumber = 72;break;case 1:sectionNumber = 8;break;case 2:sectionNumber = 16;break;case 3:sectionNumber = 24;break;case 4:sectionNumber = 32;break;default:break;}return sectionNumber;
}
UICollectionView左右切换,需要将pagingEnabled设置为YES。
界面上用到了UIPageControl,由于UICollectionView继承UIScrollView。不同section的页码不一样,所以在scrollViewDidEndDecelerating方法中更改UIPageControl的numberOfPages与currentPage。
/** 手指滑动屏幕时,视图停止滚动会调用此方法 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {NSInteger collectionPage = scrollView.contentOffset.x/scrollView.frame.size.width;NSInteger aIndex = 0;NSInteger sectionIndex = 0;for (NSInteger index = 0; index < self.sectionPageNumbers.count; index ++) {NSString *sectionPage = [self.sectionPageNumbers objectAtIndex:index];aIndex = aIndex+[sectionPage integerValue];if (collectionPage >= 0 && collectionPage < aIndex) {sectionIndex = index;break;}}NSString *sectionCount = [self.sectionPageNumbers objectAtIndex:sectionIndex];NSLog(@"sectionCount:%@",sectionCount);NSInteger preCount = 0;for (NSInteger i = 0; i < sectionIndex; i++) {NSString *sectionPage = [self.sectionPageNumbers objectAtIndex:i];preCount = preCount + sectionPage.integerValue;}NSInteger sectionPageCount = sectionCount.integerValue;NSInteger sectionCurPage = collectionPage - preCount;NSLog(@"sectionPageCount:%ld",(long)sectionPageCount);NSLog(@"sectionCurPage:%ld",(long)sectionCurPage);self.emojiView.pageControl.numberOfPages = sectionPageCount;self.emojiView.pageControl.currentPage = sectionCurPage;
}
整体使用UICollectionView代理delegate方法代码如下
#import "INEmotionPresenter.h"#define kCustomEmotionScreenWidth [UIScreen mainScreen].bounds.size.width@interface INCollectionSectionPageRange : NSObject@property (nonatomic, assign) NSString *beginNumber;
@property (nonatomic, assign) NSString *endNumber;@end@implementation INCollectionSectionPageRange@end@implementation INEmotionPresenter#pragma mark - 注册cell
/**注册cell*/
- (void)registerCollectionCell {[self.emojiView.collectionView registerClass:[INEmotionSystemEmojiCell class] forCellWithReuseIdentifier:kEmotionEmojiSystemIdentifier];[self.emojiView.collectionView registerClass:[INEmotionCustomEmojiCell class] forCellWithReuseIdentifier:kEmotionEmojiCustomIdentifier];
}#pragma mark - UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {UIEdgeInsets contentInset = collectionView.contentInset;NSInteger columnCount = 4;NSInteger rowCount = 2;if (indexPath.section == 0) {columnCount = 8;rowCount = 3;}CGFloat w = (CGRectGetWidth(collectionView.bounds) - contentInset.left - contentInset.right)/ columnCount;CGFloat h = (CGRectGetHeight(collectionView.bounds) - contentInset.top - contentInset.bottom)/rowCount;return CGSizeMake(w, h);
}- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {return 0.0;
}- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {return 0.0;
}#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 5;
}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {NSInteger sectionNumber = 60;switch (section) {case 0:sectionNumber = 72;break;case 1:sectionNumber = 8;break;case 2:sectionNumber = 16;break;case 3:sectionNumber = 24;break;case 4:sectionNumber = 32;break;default:break;}return sectionNumber;
}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {if (indexPath.section == 0) {//emoji表情INEmotionSystemEmojiCell *cell = (INEmotionSystemEmojiCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kEmotionEmojiSystemIdentifier forIndexPath:indexPath];cell.emojiLabel.text = @"";cell.emojiLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.item];cell.cellNumber = [NSString stringWithFormat:@"%ld",(long)indexPath.item];return cell;}//自定义表情贴图INEmotionCustomEmojiCell *cell = (INEmotionCustomEmojiCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kEmotionEmojiCustomIdentifier forIndexPath:indexPath];cell.cellNumber = [NSString stringWithFormat:@"%ld",(long)indexPath.item];return cell;
}- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {}- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {NSInteger collectionPage = scrollView.contentOffset.x/scrollView.frame.size.width;NSInteger aIndex = 0;NSInteger sectionIndex = 0;for (NSInteger index = 0; index < self.sectionPageNumbers.count; index ++) {NSString *sectionPage = [self.sectionPageNumbers objectAtIndex:index];aIndex = aIndex+[sectionPage integerValue];if (collectionPage >= 0 && collectionPage < aIndex) {sectionIndex = index;break;}}NSString *sectionCount = [self.sectionPageNumbers objectAtIndex:sectionIndex];NSLog(@"sectionCount:%@",sectionCount);NSInteger preCount = 0;for (NSInteger i = 0; i < sectionIndex; i++) {NSString *sectionPage = [self.sectionPageNumbers objectAtIndex:i];preCount = preCount + sectionPage.integerValue;}NSInteger sectionPageCount = sectionCount.integerValue;NSInteger sectionCurPage = collectionPage - preCount;NSLog(@"sectionPageCount:%ld",(long)sectionPageCount);NSLog(@"sectionCurPage:%ld",(long)sectionCurPage);self.emojiView.pageControl.numberOfPages = sectionPageCount;self.emojiView.pageControl.currentPage = sectionCurPage;
}#pragma mark - SETTER/GETTER
- (NSMutableArray *)sectionPageNumbers {if (!_sectionPageNumbers) {_sectionPageNumbers = [NSMutableArray arrayWithCapacity:0];[_sectionPageNumbers addObject:@"3"];[_sectionPageNumbers addObject:@"1"];[_sectionPageNumbers addObject:@"2"];[_sectionPageNumbers addObject:@"3"];[_sectionPageNumbers addObject:@"4"];}return _sectionPageNumbers;
}- (INEmotionConfig *)emojiConfig {if (!_emojiConfig) {_emojiConfig = [[INEmotionConfig alloc] init];}return _emojiConfig;
}- (INEmotionInteractor *)emojiInteractor {if (!_emojiInteractor) {_emojiInteractor = [[INEmotionInteractor alloc] init];}return _emojiInteractor;
}- (INEmotionView *)emojiView {if (!_emojiView) {_emojiView = [[INEmotionView alloc] initWithFrame:CGRectZero];}return _emojiView;
}@end
2.3 实现表情的排列UICollectionViewFlowLayout
由于emoji表情需要3行8列,自定义贴图表情需要2行4列排列。我这里实现一下UICollectionViewFlowLayout
要在layoutAttributesForItemAtIndexPath中区分,如果section为0,则为3行8列;否则为2行4列。
INEmotionFlowLayout.h
#import <UIKit/UIKit.h>@interface INEmotionFlowLayout : UICollectionViewFlowLayout- (UICollectionViewLayoutAttributes *)customLayoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;@end
INEmotionFlowLayout.m
#import "INEmotionFlowLayout.h"#define kLayScreenWidth [UIScreen mainScreen].bounds.size.width@interface INEmotionFlowLayout () <UICollectionViewDelegateFlowLayout>@property (strong, nonatomic) NSMutableArray *allAttributes;@property (nonatomic, assign) NSInteger currentRow;@property (nonatomic, assign) NSInteger currentCol;@end@implementation INEmotionFlowLayout-(instancetype)init
{if (self = [super init]){}return self;
}- (void)prepareLayout
{[super prepareLayout];self.allAttributes = [NSMutableArray array];NSInteger sections = [self.collectionView numberOfSections];for (int i = 0; i < sections; i++){NSMutableArray * tmpArray = [NSMutableArray array];NSUInteger count = [self.collectionView numberOfItemsInSection:i];for (NSUInteger j = 0; j<count; j++) {NSIndexPath *indexPath = [NSIndexPath indexPathForItem:j inSection:i];UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];[tmpArray addObject:attributes];}[self.allAttributes addObject:tmpArray];}
}- (CGSize)collectionViewContentSize
{return [super collectionViewContentSize];
}- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{NSUInteger item = indexPath.item;NSUInteger x;NSUInteger y;[self targetPositionWithItem:indexPath resultX:&x resultY:&y];NSUInteger item2 = [self originItemAtX:x y:y indexPath:indexPath];NSIndexPath *theNewIndexPath = [NSIndexPath indexPathForItem:item2 inSection:indexPath.section];UICollectionViewLayoutAttributes *theNewAttr = [super layoutAttributesForItemAtIndexPath:theNewIndexPath];theNewAttr.indexPath = indexPath;return theNewAttr;
}- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{NSArray *attributes = [super layoutAttributesForElementsInRect:rect];NSMutableArray *tmp = [NSMutableArray array];for (UICollectionViewLayoutAttributes *attr in attributes) {for (NSMutableArray *attributes in self.allAttributes){for (UICollectionViewLayoutAttributes *attr2 in attributes) {if (attr.indexPath.item == attr2.indexPath.item) {[tmp addObject:attr2];break;}}}}return tmp;
}- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{return YES;
}// 根据 item 计算目标item的位置
// x 横向偏移 y 竖向偏移
- (void)targetPositionWithItem:(NSIndexPath *)indexPathresultX:(NSUInteger *)xresultY:(NSUInteger *)y
{NSInteger columnCount = 4;NSInteger rowCount = 2;if (indexPath.section == 0) {columnCount = 8;rowCount = 3;}NSInteger item = indexPath.item;NSUInteger page = item/(columnCount*rowCount);NSUInteger theX = item % columnCount + page * columnCount;NSUInteger theY = item / columnCount - page * rowCount;if (x != NULL) {*x = theX;}if (y != NULL) {*y = theY;}}// 根据偏移量计算item
- (NSUInteger)originItemAtX:(NSUInteger)xy:(NSUInteger)yindexPath:(NSIndexPath *)indexPath
{NSInteger columnCount = 4;NSInteger rowCount = 2;if (indexPath.section == 0) {columnCount = 8;rowCount = 3;}NSUInteger item = x * rowCount + y;return item;
}- (UICollectionViewLayoutAttributes *)customLayoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {return [self layoutAttributesForItemAtIndexPath:indexPath];
}@end
2.4 emoji表情的UICollectionViewCell
继承UICollectionViewCell实现INEmotionSystemEmojiCell表情
INEmotionSystemEmojiCell.h
#import <UIKit/UIKit.h>
#import "UIColor+Addition.h"@interface INEmotionSystemEmojiCell : UICollectionViewCell@property (nonatomic, strong) UIImageView *emojiImageView;@property (nonatomic, strong) UILabel *emojiLabel;/**cell的序号*/
@property (nonatomic, strong) NSString *cellNumber;/**按照序号,从小到大@param cell cell@return 排序*/
- (NSComparisonResult)sortAscCells:(INEmotionSystemEmojiCell *)cell;@end
INEmotionSystemEmojiCell.m
#import "INEmotionSystemEmojiCell.h"static CGFloat kEmotionEmojiSize = 40.0;@implementation INEmotionSystemEmojiCell- (instancetype)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self) {self.emojiImageView = [[UIImageView alloc] initWithFrame:CGRectMake((CGRectGetWidth(self.bounds) - kEmotionEmojiSize)/2, (CGRectGetHeight(self.bounds) - kEmotionEmojiSize)/2, kEmotionEmojiSize, kEmotionEmojiSize)];self.emojiImageView.backgroundColor = [UIColor randomColor];self.emojiImageView.layer.cornerRadius = kEmotionEmojiSize/2;self.emojiImageView.layer.masksToBounds = YES;[self addSubview:self.emojiImageView];self.emojiLabel = [[UILabel alloc] initWithFrame:CGRectMake((CGRectGetWidth(self.bounds) - kEmotionEmojiSize)/2, (CGRectGetHeight(self.bounds) - kEmotionEmojiSize)/2, kEmotionEmojiSize, kEmotionEmojiSize)];self.emojiLabel.textColor = [UIColor grayColor];self.emojiLabel.textAlignment = NSTextAlignmentCenter;[self addSubview:self.emojiLabel];}return self;
}- (void)layoutSubviews {[super layoutSubviews];self.emojiImageView.frame = CGRectMake((CGRectGetWidth(self.bounds) - kEmotionEmojiSize)/2, (CGRectGetHeight(self.bounds) - kEmotionEmojiSize)/2, kEmotionEmojiSize, kEmotionEmojiSize);self.emojiLabel.frame = CGRectMake((CGRectGetWidth(self.bounds) - kEmotionEmojiSize)/2, (CGRectGetHeight(self.bounds) - kEmotionEmojiSize)/2, kEmotionEmojiSize, kEmotionEmojiSize);
}/**按照序号,从小到大@param cell cell@return 排序*/
- (NSComparisonResult)sortAscCells:(INEmotionSystemEmojiCell *)cell {//先按照时间排序NSComparisonResult result = [self.cellNumber compare:cell.cellNumber];return result;
}@end
2.5 自定义贴图表情的UICollectionViewCell
INEmotionCustomEmojiCell.h
#import <UIKit/UIKit.h>
#import "UIColor+Addition.h"@interface INEmotionCustomEmojiCell : UICollectionViewCell@property (nonatomic, strong) UIImageView *emojiImageView;/**cell的序号*/
@property (nonatomic, strong) NSString *cellNumber;/**按照序号,从小到大@param cell cell@return 排序*/
- (NSComparisonResult)sortAscCells:(INEmotionCustomEmojiCell *)cell;@end
INEmotionCustomEmojiCell.m
#import "INEmotionCustomEmojiCell.h"static CGFloat kCustomEmotionEmojiSize = 80.0;@implementation INEmotionCustomEmojiCell- (instancetype)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self) {self.emojiImageView = [[UIImageView alloc] initWithFrame:CGRectMake((CGRectGetWidth(self.bounds) - kCustomEmotionEmojiSize)/2, (CGRectGetHeight(self.bounds) - kCustomEmotionEmojiSize)/2, kCustomEmotionEmojiSize, kCustomEmotionEmojiSize)];self.emojiImageView.backgroundColor = [UIColor randomColor];self.emojiImageView.layer.cornerRadius = 4;self.emojiImageView.layer.masksToBounds = YES;[self addSubview:self.emojiImageView];}return self;
}- (void)layoutSubviews {[super layoutSubviews];self.emojiImageView.frame = CGRectMake((CGRectGetWidth(self.bounds) - kCustomEmotionEmojiSize)/2, (CGRectGetHeight(self.bounds) - kCustomEmotionEmojiSize)/2, kCustomEmotionEmojiSize, kCustomEmotionEmojiSize);
}/**按照序号,从小到大@param cell cell@return 排序*/
- (NSComparisonResult)sortAscCells:(INEmotionCustomEmojiCell *)cell {//先按照时间排序NSComparisonResult result = [self.cellNumber compare:cell.cellNumber];return result;
}@end
至此整个效果的代码实现完了。
三、小结
iOS开发-聊天emoji表情与自定义动图表情左右滑动控件.使用UICollectionView实现。
学习记录,每天不停进步。
相关文章:
iOS开发-聊天emoji表情与自定义动图表情左右滑动控件
iOS开发-聊天emoji表情与自定义动图表情左右滑动控件 之前开发中遇到需要实现聊天emoji表情与自定义动图表情左右滑动控件。使用UICollectionView实现。 一、效果图 二、实现代码 UICollectionView是一种类似于UITableView但又比UITableView功能更强大、更灵活的视图&#x…...
Mybatis plus 存储 List、Map
目录 一、前提概要1.1 支持环境1.2 需求场景 二、需求实现2.1 非自定义数据类型,List、Map2.2 自定义类型数据类型 一、前提概要 1.1 支持环境 数据库支持:MySql版本要求 5.7 1.2 需求场景 使用MySQL数据库存储时,由于业务要求实体类中特…...
Electron 系统通知 Notification 实践指南
系统通知是桌面应用的常见功能,用于给用户发送提醒(刷下存在感 🙂),还能帮定点击事件以便后续的操作。 Electron 自带通知模块,下方代码是一个简单的示例 const { Notification } require(electron)cons…...
配置代理——解决跨域问题(详解)
之前写项目的时候总会遇到配置代理的问题,可是配置了之后有时有用,有时就没有用,自己之前学的也是懵懵懂懂,于是专门花了一个小时去了解了如何配置代理跨域,然后在此记录一下,方便自己以后查阅。 一、 常用…...
VScode 避免逗号、括号时自动补全
设置项 控制是否应在遇到提交字符时接受建议。例如,在JavaScript中,半角分号(;)可以为提交字符,能够在接受建议的同时键入该字符。 "editor.acceptSuggestionOnCommitCharacter": false起因 比如打伪代码的时候输入一些缺少上下…...
【数学建模】时间序列分析
文章目录 1. 条件2. 模型分类3. SPSS处理时间序列 1. 条件 1.使用于具有时间、数值两种要素 2.数据具有周期性可以使用时间序列分解 2. 模型分类 叠加模型【YTSCI】 序列的季节波动变化越来越大,反映变动之间的关系发生变化乘积序列【YTSC*I】 时间序列波动保持恒…...
Spring使用注解进行对象装配(DI)
文章目录 一. 什么是对象装配二. 三种注入方式1. 属性注入2. 构造方法注入3. Setter注入 三. 三种注入方式的优缺点四. 综合练习 通过五大类注解可以更便捷的将对象存储到 Spring 中,同样也可以使用注解将已经储存的对象取出来,直接赋值到注解所在类的一…...
数学建模-蒙特卡洛模拟
%% 蒙特卡罗用于模拟三门问题 clear;clc %% (1)预备知识 % randi([a,b],m,n)函数可在指定区间[a,b]内随机取出大小为m*n的整数矩阵 randi([1,5],5,8) %在区间[1,5]内随机取出大小为5*8的整数矩阵 % 2 5 4 5 3 1 4 2 %…...
Pearson correlation皮尔逊相关性分析
在参数检验的相关性分析方法主要是皮尔逊相关(Pearson correlation)。既然是参数检验方法,肯定是有一些前提条件。皮尔逊相关的前提是必须满足以下几个条件: 变量是连续变量;比较的两个变量必须来源于同一个总体&…...
P1036 [NOIP2002 普及组] 选数
题目描述 已知 �n 个整数 �1,�2,⋯ ,��x1,x2,⋯,xn,以及 11 个整数 �k(�<�k<n)。从 �n 个整数中任选 �k 个…...
css终极方案PostCSS
一见如故 原理 所有的css框架都在一样的事,那就是由一个css生成一个新的css,那么postcss就来做了一个抽离: 1、将原有的css解析成抽象语法树 2、中间经过若干个插件 3、重新文本化,形成新的css postcss.config.js module.expor…...
代码随想录算法训练营第三天|417. 太平洋大西洋水流问题|24. 两两交换链表中的节点|19.删除链表的倒数第N个节点|面试题 02.07. 链表相交|
417. 太平洋大西洋水流问题 水往高处流,先记录两个海祥往高处流所能留到的地址,之后将他们的合并区域进行输出 static const int dirs[4][2] {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};class Solution { public:vector<vector<int>> heights;v…...
【Java】Spring——创建Spring + 对Spring的存储 /读取对象操作
文章目录 前言一、创建Spring项目二、向Spring容器中存储 Bean 对象三、从Spring容器中读取 Bean 对象得到Spring上下文对象得到 Bean 对象 总结 前言 本人是一个普通程序猿!分享一点自己的见解,如果有错误的地方欢迎各位大佬莅临指导,如果你也对编程感兴趣的话,互…...
RTPSv2.2(中文版)
实时发布订阅协议 (RTPS) DDS互操作性 有线协议规范 V2.2 (2014-09-01正式发布) https://www.omg.org/spec/DDSI-RTPS/2.2/PDF 目 录 1 范围Scope 9 2 一致性Conformance 9 3 参考文献References 9 4 术语和定义Terms a…...
Django学习笔记-视图(views)的使用
Django中可以使用views进行管理,类似于WPF的MVVM的ViewModel层,也相当于MVC架构的模Controller层。 一、基于函数的视图FBV(Function-Based View) 通过定义一个函数,包含HttpRequest对象作为参数,用来接受…...
四姑娘山三日游
趁着小孩放暑假,从昆明回来之后,直接自驾到四姑娘山。 第一天 成都-四川省阿坝藏族羌族自治州小金县日隆镇(20230711) 大概9:30从成都市郫都区出发,路线如下:郫都—都江堰–映秀—耿达—卧龙—四姑娘山,中途翻过巴朗…...
spinal HDL语法学习
1 赋值语句 用来声明变量 : 用来对变量进行赋值 2 when otherwise前面是否有"."与otherwise是否换行有关系 3 case class 对Bundle进行扩展时,需要case class case class和class主要有两点区别: (1)case class不需…...
GRE TAP的工作原理与5G工业物联网中的应用
随着互联网新技术的发展以及智能化水平的提高,各企业对实时数据传输的需求也在不断提升,企业愈发重视数据中心的建设,以保障企业内网数据安全。 GRE(Generic Routing Encapsulation,通用路由封装)协议属于…...
NFT和数字藏品的安全方案解析
一、NFT和数字藏品 01 NFT是什么? NFT 是Non-Fungible Tokens 的缩写,意思是不可互换的代币,它是相对于可互换的代币而言的。不可互换的代币也称为非同质代币。什么是可互换的代币?比如BTC(比特币)、ETH&…...
第四篇-Miniconda3-CentOS7-安装
Miniconda3-CentOS7-安装 Conda可以创建你需要的不同版本的Python环境,做的各个环境之间隔离,可以有助于我们一台主机部署不同版本运行环境 下载 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh执行 sh Miniconda3-latest-Linux-…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
