iOS开发-聊天emoji表情与自定义动图表情左右滑动控件

news2024/9/23 21:24:10

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 *)indexPath
                       resultX:(NSUInteger *)x
                       resultY:(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)x
                          y:(NSUInteger)y
                  indexPath:(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实现。

学习记录,每天不停进步。

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

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

相关文章

window.location.href is not a function

在使用uniapp跳转到外部页面时&#xff0c;使用window.location.href报错 解决&#xff1a; 当出现"window.location.href is not a function"的错误时&#xff0c;这通常是因为在某些浏览器中&#xff0c;window.location.href被视为只读属性&#xff0c;而不是函…

时频分析方法的matlab实现

傅里叶变换 function [ output_args ] example3_7( input_args ) %EXAMPLE3_7 Summary of this function goes here % Detailed explanation goes here clc; clear; fs12800;%采样频率 s1load(Sig1.txt); s2load(Sig2.txt); lslength(s1); figure(1) subplot(211) plot…

c++11 标准模板(STL)(std::basic_filebuf)(八)

定义于头文件 <fstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_filebuf : public std::basic_streambuf<CharT, Traits> std::basic_filebuf 是关联字符序列为文件的 std::basic_streambuf 。输入序…

【力扣每日一题】2023.7.29 环形链表

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一个链表&#xff0c;让我们判断这个链表是否有环。我们可以直接遍历这个链表&#xff0c;最后能走到链表末尾也就是空指针那就…

Go语言进阶语法八万字详解,通俗易懂

文章目录 File文件操作FileInfo接口权限打开模式File操作文件读取 I/O操作io包 文件复制io包下的Read()和Write()io包下的Copy()ioutil包总结 断点续传Seeker接口断点续传 bufio包bufio包原理Reader对象Writer对象 bufio包bufio.Readerbufio.Writer ioutil包ioutil包的方法示例…

wps图表怎么改横纵坐标,MLP 多层感知器和CNN卷积神经网络区别

目录 wps表格横纵坐标轴怎么设置&#xff1f; MLP (Multilayer Perceptron) 多层感知器 CNN (Convolutional Neural Network) 卷积神经网络 多层感知器MLP&#xff0c;全连接网络&#xff0c;DNN三者的关系 wps表格横纵坐标轴怎么设置&#xff1f; 1、打开表格点击图的右侧…

LeetCode559. N 叉树的最大深度

559. N 叉树的最大深度 文章目录 [559. N 叉树的最大深度](https://leetcode.cn/problems/maximum-depth-of-n-ary-tree/)一、题目二、题解方法一&#xff1a;迭代方法二&#xff1a;递归 一、题目 给定一个 N 叉树&#xff0c;找到其最大深度。 最大深度是指从根节点到最远叶…

互联网医院建设|互联网医疗系统|互联网医院开发功能及特点

互联网医院是一种通过互联网技术与医疗服务相结合的创新模式。它可以让患者在家中或办公室&#xff0c;通过智能终端与医生进行在线咨询、预约挂号、开具电子处方等。这种模式打破了传统医疗的时间与空间限制&#xff0c;为患者提供了更为便捷、高效的医疗服务。 互联网医院功能…

LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443

1、问题&#xff1a; https://github.com/CocoaPods/Specs.git/&#xff1a;LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443的解决办法 出现这个问题的原因基本都是代理的问题&#xff1a; 只需要加上代理就可以了&#xff1a; #http代理 git conf…

算法39:Excel 表列序号

一、需求 给你一个字符串 columnTitle &#xff0c;表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如&#xff1a; A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例 1&#xff1a; 输入: columnTitle “A” 输出: 1 示例 2&…

Elasticsearch:通过动态修剪实现更快的基数聚合

作者&#xff1a;Adrien Grand Elasticsearch 8.9 通过支持动态修剪&#xff08;dynamic pruning&#xff09;引入了基数聚合加速。 这种优化需要满足特定的条件才能生效&#xff0c;但一旦实现&#xff0c;通常会产生惊人的结果。 我们观察到&#xff0c;通过此更改&#xff0…

向量vector与sort()

运行代码&#xff1a; //向量与sort() #include"std_lib_facilities.h" //声明Item类 struct Item {string name;int iid;double value;friend istream& operator>>(istream& is, Item& ii);friend ostream& operator<<(ostream& o…

阿里 120W 年薪架构师力荐 750 页微服务架构深度解析笔记

前言 当前&#xff0c;微服务架构在国内正处于蓬勃发展的阶段&#xff0c;无论是大型互联网公司还是传统的 IT 企业&#xff0c;纷纷采用微服务架构构建系统。 在过去几年里&#xff0c;DevOps、云原生、面向演进式架构等理念已经深入人心&#xff0c;围绕微服务生态也出现了…

导致内存泄漏的因素及解决方式

导致内存泄漏的因素 一、全局变量 因为全局变量不被js垃圾回收机制所回收&#xff0c;所以在使用全局变量时要小心。避免在想使用局部变量因为疏忽导致该变量流失到全局&#xff0c;如未声明变量&#xff0c;却直接对其进行赋值&#xff0c;就会导致该变量在全局创建&#xf…

Python Numpy入门基础(一)创建数组

入门基础&#xff08;一&#xff09; 创建数组 1- np.array() 参数众多&#xff0c;初学时只要关注基本用法。 array(...)array(object, dtypeNone, *, copyTrue, orderK, subokFalse, ndmin0,likeNone)Create an array.Parameters----------object : array_likeAn array, …

CAN通信协议

CAN 物理电平 以高速CAN为例 有电压差&#xff08;2.5V&#xff09;为显性&#xff0c;逻辑0无电压差为隐性&#xff0c;逻辑1 帧结构 SOF 恒为显性&#xff0c;逻辑0 仲裁段 当有多个设备发送数据&#xff0c;产生总线冲突时&#xff0c;来判断一个先后顺序由于总线是线与…

重学C++系列之友元

一、什么是友元 在C中&#xff0c;为了提高程序的效率&#xff0c;在一些场景下&#xff0c;引入友元&#xff0c;但同时类的封装性就会被破坏。 二、怎么实现友元 友元关键字&#xff08;friend&#xff09; // 在类中声明另一个类的成员函数来做为友元函数 // 以关键字&…

golangd\pycharm-ai免费代码助手安装使用gpt4-免费使用--[推荐]

golangd-ai免费代码助手安装使用,pycharm可以使用&#xff0c;估计只要是xx的ide都是可以使用这个插件 目前GPT4以及gpt的大规模使用&#xff0c;如何快速掌握以及在ide中快速使用的办法&#xff0c;今天安装一款golangd编辑器的插件已经使用 一、安装以及使用 1.在golangd中…

texshop mac中文版-TeXShop for Mac(Latex编辑预览工具)

texshop for mac是一款可以在苹果电脑MAC OS平台上使用的非常不错的Mac应用软件&#xff0c;texshop for mac是一个非常有用的工具&#xff0c;广泛使用在数学&#xff0c;计算机科学&#xff0c;物理学&#xff0c;经济学等领域的合作&#xff0c;这些程序的标准tetex分布特产…

PKG内容查看工具:Suspicious Package for Mac安装教程

Suspicious Package Mac版是一款Mac平台上的查看 PKG 程序包内信息的应用&#xff0c;Suspicious Package Mac版支持查看全部包内全部文件&#xff0c;比如需要运行的脚本&#xff0c;开发者&#xff0c;来源等等。 suspicious package mac使用简单&#xff0c;只需在选择pkg安…