失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 直播间搭建实现iOS直播聊天消息界面

直播间搭建实现iOS直播聊天消息界面

时间:2022-10-19 05:04:01

相关推荐

直播间搭建实现iOS直播聊天消息界面

直播间搭建实现iOS直播聊天消息界面

近几年直播一火再火,现在的直播已经不再是主播们唱唱歌了,连老罗都已经开始直播带货,一再刷新抖音直播在线人数了。

但今天我们不是来说怎么做直播的,是来看看直播场景里的聊天消息界面是如何实现的。

估计很多人要失望了😀😀

要实现聊天消息界面,不可不用 UITableView。当几年前我开始自学开发 iOS APP 时,我就开始使用 AsyncDisplayKit,现在已经更名为:Texture。

Keeps the most complex iOS user interfaces smooth and responsive. Texture is an iOS framework built on top of UIKit that keeps even the most complex user interfaces smooth and responsive. It was originally built to make Facebook's Paper possible, and goes hand-in-hand with pop's physics-based animations — but it's just as powerful with UIKit Dynamics and conventional app designs. More recently, it was used to power Pinterest's app rewrite.

As the framework has grown, many features have been added that can save developers tons of time by eliminating common boilerplate style structures common in modern iOS apps. If you've ever dealt with cell reuse bugs, tried to performantly preload data for a page or scroll style interface or even just tried to keep your app from dropping too many frames you can benefit from integrating Texture.

参考Texture 官网

以后把每次用到的 Nodes 心得写出来,今天来说一说使用ASTableNode

初始化 ASTableNode

创建ASTableNodeUITableView一样,比较简单。

@interface TestViewController () <ASTableDataSource, ASTableDelegate>@property (nonatomic, strong) ASTableNode *tableNode;@property (nonatomic, strong) NSMutableArray *dataSource;@end复制代码

初始化:

_tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];_tableNode.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;_tableNode.backgroundColor = [UIColor.clearColor colorWithAlphaComponent:0.0];_tableNode.view.separatorStyle = UITableViewCellSeparatorStyleNone;[self.view addSubnode:_tableNode];_tableNode.frame = CGRectMake(0, self.view.bounds.size.height - 300, 300, 200);// 填充测试数据_dataSource = [NSMutableArray arrayWithArray:@[@{@"type": @"TEXT", @"text": @"你好", @"nickname": @"yemeishu"},@{@"type": @"TEXT", @"text": @"你好,这个主播不错哦~", @"nickname": @"yemeishu"},@{@"type": @"TEXT", @"text": @"现在直播还可以带货了", @"nickname": @"yemeishu"}]];_tableNode.delegate = self;_tableNode.dataSource = self;_tableNode.view.allowsSelection = NO;复制代码

UITableView一样,实现dataSorcedelegate(这里暂时不写对 Node 操作):

#pragma mark - ASTableNode- (ASCellNodeBlock)tableNode:(ASTableNode *)tableNode nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath{NSDictionary *message = self.dataSource[(NSUInteger) indexPath.row];return ^{return [[MessageNode alloc] initWithMessage: message];};}- (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section{return self.dataSource.count;}复制代码

现在可以创建 ASCellNode 子类。

编写 ASCellNode 子类

ASCellNode, as you may have guessed, is the cell class of Texture. Unlike the various cells in UIKit, ASCellNode can be used with ASTableNodes, ASCollectionNodes and ASPagerNodes, making it incredibly flexible.

ASCellNode 核心函数主要有四个,我们的重点在layoutSpecThatFits上。

-init – Thread safe initialization.

-layoutSpecThatFits: – Return a layout spec that defines the layout of your cell.

-didLoad – Called on the main thread. Good place to add gesture recognizers, etc.

-layout – Also called on the main thread. Layout is complete after the call to super which means you can do any extra tweaking you need to do.

具体MessageNode类直接看代码,只要将每个人聊天的信息发给MessageNode填充内容:

@interface MessageNode : ASCellNode- (instancetype)initWithMessage:(NSDictionary *)message;@end复制代码

这里为了简单实现效果,只是显示消息者姓名和消息内容。

#import "MessageNode.h"@interface ZJMessageNode()@property (strong, nonatomic) ASButtonNode *textNode;@end@implementation MessageNode {}- (instancetype)initWithMessage:(NSDictionary *)message {self = [super init];if (self) {_textNode = [[ASButtonNode alloc] init];NSString* nickname = @"";NSString* text = @"";if ([message[@"type"] isEqual: @"TEXT"]) {nickname = [NSString stringWithFormat:@"[%@]:",message[@"nickname"]];text = message[@"text"];} else {nickname = @"其他人";text = @"其他消息";}NSMutableAttributedString* string = [[NSMutableAttributedString alloc] initWithString:@""];NSAttributedString* nameString = [[NSAttributedString alloc] initWithString:nickname attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0],NSForegroundColorAttributeName: UIColorMakeWithHex(@"#FF9900")}];NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];paragraphStyle.lineSpacing = 5.0;NSAttributedString* textString = [[NSAttributedString alloc] initWithString: text attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0],NSForegroundColorAttributeName: UIColor.ZJ_tintColor,NSParagraphStyleAttributeName: paragraphStyle}];[string appendAttributedString:nameString];[string appendAttributedString:textString];_textNode.titleNode.attributedText = string;_textNode.titleNode.maximumNumberOfLines = 3;_textNode.backgroundImageNode.image = [UIImage as_resizableRoundedImageWithCornerRadius:8cornerColor:UIColor.clearColorfillColor: [UIColor colorWithRed:26/255.0 green:26/255.0 blue:26/255.0 alpha:0.5]];[self addSubnode:_textNode];}return self;}- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize {[_textNode.titleNode setTextContainerInset:UIEdgeInsetsMake(9, 14.5, 9, 8.5)];ASAbsoluteLayoutSpec *absoluteSpec = [ASAbsoluteLayoutSpec absoluteLayoutSpecWithChildren:@[_textNode]];// ASAbsoluteLayoutSpec's .sizing property recreates the behavior of ASDK Layout API 1.0's "ASStaticLayoutSpec"absoluteSpec.sizing = ASAbsoluteLayoutSpecSizingSizeToFit;return [ASInsetLayoutSpecinsetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 10, 10, 10)child:absoluteSpec];}@end

好了,让我们运行下 Demo,看看效果:

是不是和抖音上的聊天界面效果差不多:

解析 MessageNode

ASButtonNode

Demo 中主要用一个ASButtonNode主要有这几点考虑。

参考很多直播聊天消息显示界面,每个聊天体主要以 Text 文本为主,而且把关键的信息用不同的颜色和大小做区分,所以用NSMutableAttributedString比较合适。所以在MessageNode中主要以ASTextNode为主。在本文中,为了演示,主要拿昵称和消息内容,用函数appendAttributedString拼接在一起。要为ASTextNode添加一个半透明、圆角的「背景」层,所以需要增加一个ASImageNode。如果对于复杂的消息,需要在姓名之前增加一个类似 VIP 等级图标等,这也就有可能还需要一个ASImageNode

所以要能满足以上三点要求,最好的 Node 就是ASButtonNode

如果我们直接在MessageNode放三个元素 (一个ASTextNode,两个ASImageNode) 也能满足需要,但元素间的布局和定位就不好设计了,无形增加代码量和难度。

ASAbsoluteLayoutSpec

由于使用了ASTableNode,对每一个消息体的最大宽度默认都和ASTableNode一样。所以在布局时,如果我们采用其他的ASLayoutSpec的布局方式,呈现的结果就很难像直播窗口那样了,能够实时根据文本的长度显示,不至于每个消息体都是等宽的,不好看。

所以本文推荐使用ASAbsoluteLayoutSpec

Within ASAbsoluteLayoutSpec you can specify exact locations (x/y coordinates) of its children by setting their layoutPosition property. Absolute layouts are less flexible and harder to maintain than other types of layouts.

ASAbsoluteLayoutSpec has one property:

sizing. Determines how much space the absolute spec will take up. Options include: Default, and Size to Fit. Note that the Size to Fit option will replicate the behavior of the old ASStaticLayoutSpec.

这里我设定sizing为:

absoluteSpec.sizing = ASAbsoluteLayoutSpecSizingSizeToFit;复制代码

最后就是给各个消息体设定一个EdgeInsets,分开点,免得每个消息体都是挨着的:

[ASInsetLayoutSpecinsetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 10, 10, 10)child:absoluteSpec];复制代码

直播间搭建实现iOS直播聊天消息界面

如果觉得《直播间搭建实现iOS直播聊天消息界面》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。