我正在使用JSQMessagesViewController
在与服务器通信的应用程序中获取聊天功能。但是,聊天气泡非常难以预测,并且它们的大小永远不会正确调整。文本总是被切断,因为聊天气泡没有增加它的宽度和高度以适应我的信息。我有以下代码:
#import "ChatViewController.h"
#import "JSQMessage.h"
#import "JSQMessagesTimestampFormatter.h"
#import "JSQMessagesBubbleImage.h"
#import "JSQMessagesBubbleImageFactory.h"
#import "User.h"
#import "AuthenticationHelper.h"
#import "Chat.h"
@interface ChatViewController ()
@property(strong, nonatomic)NSMutableArray* messagesArray;
@property(strong, nonatomic)User* myUser;
@property(strong, nonatomic)NSTimer* updateTimer;
@end
@implementation ChatViewController
#pragma mark - View lifecycle
/**
* Override point for customization.
*
* Customize your view.
* Look at the properties on `JSQMessagesViewController` and `JSQMessagesCollectionView` to see what is possible.
*
* Customize your layout.
* Look at the properties on `JSQMessagesCollectionViewFlowLayout` to see what is possible.
*/
- (void)viewDidLoad
{
NSLog(@"CHAT VIEW DID LOAD");
[super viewDidLoad];
User* me = ([AuthenticationHelper sharedInstance]).loggedInUser;
self.title = @"JSQMessages";
self.messagesArray = [[NSMutableArray alloc] init];
self.senderId = [NSString stringWithFormat:@"%i", [me.id intValue]];
self.senderDisplayName = me.fullName;
self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
self.showLoadEarlierMessagesHeader = NO;
self.inputToolbar.contentView.leftBarButtonItem = nil;
self.inputToolbar.maximumHeight = 150;
//TODO: create scheduled task to pull messages from the server.
}
-(void)updateMessages {
[Chat getChatsForId:self.user.id SuccessCallback:^(NSArray* chats){
self.messagesArray = [chats mutableCopy];
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
});
} errorCallback:^(NSString* error) {
}];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.updateTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0 target: self
selector: @selector(updateMessages) userInfo: nil repeats: YES];
[self.updateTimer fire];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.collectionView.collectionViewLayout.springinessEnabled = NO;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.updateTimer = nil;
}
#pragma mark - JSQMessagesViewController method overrides
- (void)didPressSendButton:(UIButton *)button
withMessageText:(NSString *)text
senderId:(NSString *)senderId
senderDisplayName:(NSString *)senderDisplayName
date:(NSDate *)date
{
NSLog(@"SENDER ID IS %@", senderId);
NSLog(@"SENDER DISPLAY NAME IS %@", senderDisplayName);
NSLog(@"DATE IS %@", date.description);
[Chat createChat:@{@"to_user_id" : self.user.id, @"from_user_id" : ([AuthenticationHelper sharedInstance]).loggedInUser.id, @"message" : text} successCallback:^(Chat* chat) {
[self.messagesArray addObject:chat];
dispatch_async(dispatch_get_main_queue(), ^{
[self finishSendingMessageAnimated:YES];
});
} errorCallback:^(NSString* error) {
}];
}
#pragma mark - JSQMessages CollectionView DataSource
- (id<JSQMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [self.messagesArray objectAtIndex:indexPath.item];
}
- (id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
{
/**
* You may return nil here if you do not want bubbles.
* In this case, you should set the background color of your collection view cell's textView.
*
* Otherwise, return your previously created bubble image data objects.
*/
Chat* chat = [self.messagesArray objectAtIndex:indexPath.item];
if ([chat.toUserId intValue] == [self.user.id intValue]) {
return [[[JSQMessagesBubbleImageFactory alloc] init] outgoingMessagesBubbleImageWithColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"tableBackground.png"]]];
}
return [[[JSQMessagesBubbleImageFactory alloc] init] incomingMessagesBubbleImageWithColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"TopNavBarBackground.png"]]];
}
- (id<JSQMessageAvatarImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView avatarImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
{
return nil;
}
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath
{
/**
* This logic should be consistent with what you return from `heightForCellTopLabelAtIndexPath:`
* The other label text delegate methods should follow a similar pattern.
*
* Show a timestamp for every 3rd message
*/
if (indexPath.item % 3 == 0) {
JSQMessage *message = [self.messagesArray objectAtIndex:indexPath.item];
return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date];
}
return nil;
}
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForMessageBubbleTopLabelAtIndexPath:(NSIndexPath *)indexPath
{
JSQMessage *message = [self.messagesArray objectAtIndex:indexPath.item];
if ([message.senderId isEqualToString:self.senderId]) {
return nil;
}
if (indexPath.item - 1 > 0) {
JSQMessage *previousMessage = [self.messagesArray objectAtIndex:indexPath.item - 1];
if ([[previousMessage senderId] isEqualToString:message.senderId]) {
return nil;
}
}
return [[NSAttributedString alloc] initWithString:message.senderDisplayName];
}
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellBottomLabelAtIndexPath:(NSIndexPath *)indexPath
{
return nil;
}
#pragma mark - UICollectionView DataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.messagesArray count];
}
- (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
/**
* Override point for customizing cells
*/
JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath];
/**
* Configure almost *anything* on the cell
*
* Text colors, label text, label colors, etc.
*
*
* DO NOT set `cell.textView.font` !
* Instead, you need to set `self.collectionView.collectionViewLayout.messageBubbleFont` to the font you want in `viewDidLoad`
*
*
* DO NOT manipulate cell layout information!
* Instead, override the properties you want on `self.collectionView.collectionViewLayout` from `viewDidLoad`
*/
/*
JSQMessage *msg = [self.demoData.messages objectAtIndex:indexPath.item];
if (!msg.isMediaMessage) {
if ([msg.senderId isEqualToString:self.senderId]) {
cell.textView.textColor = [UIColor blackColor];
}
else {
cell.textView.textColor = [UIColor whiteColor];
}
cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor,
NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) };
}
*/
// cell.textView.text = ((Chat*)[self.messagesArray objectAtIndex:indexPath.row]).message;
return cell;
}
#pragma mark - Adjusting cell label heights
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath
{
/**
* Each label in a cell has a `height` delegate method that corresponds to its text dataSource method
*/
/**
* This logic should be consistent with what you return from `attributedTextForCellTopLabelAtIndexPath:`
* The other label height delegate methods should follow similarly
*
* Show a timestamp for every 3rd message
*/
if (indexPath.item % 3 == 0) {
return kJSQMessagesCollectionViewCellLabelHeightDefault;
}
return 0.0f;
}
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForMessageBubbleTopLabelAtIndexPath:(NSIndexPath *)indexPath
{
/**
* iOS7-style sender name labels
*/
JSQMessage *currentMessage = [self.messagesArray objectAtIndex:indexPath.item];
if ([[currentMessage senderId] isEqualToString:self.senderId]) {
return 0.0f;
}
if (indexPath.item - 1 > 0) {
JSQMessage *previousMessage = [self.messagesArray objectAtIndex:indexPath.item - 1];
if ([[previousMessage senderId] isEqualToString:[currentMessage senderId]]) {
return 0.0f;
}
}
return kJSQMessagesCollectionViewCellLabelHeightDefault;
}
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellBottomLabelAtIndexPath:(NSIndexPath *)indexPath
{
return 0.0f;
}
#pragma mark - Responding to collection view tap events
- (void)collectionView:(JSQMessagesCollectionView *)collectionView
header:(JSQMessagesLoadEarlierHeaderView *)headerView didTapLoadEarlierMessagesButton:(UIButton *)sender
{
NSLog(@"Load earlier messages!");
}
- (void)collectionView:(JSQMessagesCollectionView *)collectionView didTapAvatarImageView:(UIImageView *)avatarImageView atIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Tapped avatar!");
}
- (void)collectionView:(JSQMessagesCollectionView *)collectionView didTapMessageBubbleAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Tapped message bubble!");
}
- (void)collectionView:(JSQMessagesCollectionView *)collectionView didTapCellAtIndexPath:(NSIndexPath *)indexPath touchLocation:(CGPoint)touchLocation
{
NSLog(@"Tapped cell at %@!", NSStringFromCGPoint(touchLocation));
}
@end
我像演示一样调整了单元格标签的高度,但是由于没有调整气泡的大小,文本一直被截断。这是我使用Chat
对象而不是JSQMessage
对象的方式吗?
任何帮助或建议将不胜感激,因为我已经坚持了一段时间。谢谢。