crypt crypt - 22 days ago 16
iOS Question

The bubble image arrow is always on the right direction. How to change green bubbles' arrow direction to left?

enter image description here

In my JSQMessagesViewController, when I load text message bubbles, the arrow direction is always right side.
How to change arrow direction to left for green bubbles??

My Code:

@interface AckChatViewController (){

JSQMessagesBubbleImage *outgoingBubbleImageView;
JSQMessagesBubbleImage *incomingBubbleImageView;

JSQMessagesAvatarImage *currentUserAvatar, *friendAvatar;
NSMutableArray *messages;
}

@end


@implementation AckChatViewController

pragma mark - life cycle methods



- (void)viewDidLoad {
[super viewDidLoad];

self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
self.navigationController.navigationBar.topItem.title = @"";
//initial things for JSQMessageViewController
[self setupBubbles];
messages = [NSMutableArray new];

AllUserDetailsModel *temp = [[AllUserDetailsModel alloc] initWithDictionary:[Neo_Constants getSavedDataFromUserDafaults:USER_INFO_DICTIONARY]];

self.senderId = [NSString stringWithFormat:@"%@",temp.user_id];

self.senderDisplayName = @"";

self.automaticallyScrollsToMostRecentMessage = YES;

//remove attachment button
self.inputToolbar.contentView.leftBarButtonItem = nil;

currentUserAvatar = [JSQMessagesAvatarImage avatarImageWithPlaceholder: [self cropAvatarImages:[UIImage imageNamed:[self defaultImageForGender:temp.userDetails.gender]]]];

friendAvatar = [JSQMessagesAvatarImage avatarImageWithPlaceholder: [self cropAvatarImages:[UIImage imageNamed:[self defaultImageForGender:self.friendUserDetails.userDetails.gender]]]];

NSString *imageUrlString = temp.userDetails.profile_pic;

[self avatarImagesForUrlString:imageUrlString andOnCompletion:^(UIImage *image) {

if(image){
currentUserAvatar.avatarImage = image;
}
}];

[self avatarImagesForUrlString:self.friendUserDetails.userDetails.profile_pic andOnCompletion:^(UIImage *image) {

if(image){
friendAvatar.avatarImage = image;
}
}];

//set profile pic and name on navigation bar
[self setNavigationBarTitleView];

[self loadPreviousChatWithPageCount:0];

}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}


pragma mark - JSQ Setups



-(void)setupBubbles{

JSQMessagesBubbleImageFactory *bubbleImageFactory = [JSQMessagesBubbleImageFactory new];

outgoingBubbleImageView = [bubbleImageFactory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleBlueColor]];

incomingBubbleImageView = [bubbleImageFactory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleGreenColor]];

}


pragma mark Collection view JSQ



-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

return messages.count;
}

-(id<JSQMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath{

return messages[indexPath.item];
}

-(id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath{

JSQMessage *message = messages[indexPath.item];

if([message.senderId isEqualToString:self.senderId]){

return outgoingBubbleImageView;

}else{

return incomingBubbleImageView;

}

}


-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath];

JSQMessage *message = messages[indexPath.item];
if([message.senderId isEqualToString:self.senderId]){

[cell.textView setTextColor:[UIColor whiteColor]];
}else{

[cell.textView setTextColor:[UIColor blackColor]];
}

return cell;
}

-(id<JSQMessageAvatarImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView avatarImageDataForItemAtIndexPath:(NSIndexPath *)indexPath{

JSQMessage *message = messages[indexPath.item];

if([message.senderId isEqualToString:self.senderId]){

return currentUserAvatar;
}else{

return friendAvatar;
}
}

-(void)collectionView:(JSQMessagesCollectionView *)collectionView header:(JSQMessagesLoadEarlierHeaderView *)headerView didTapLoadEarlierMessagesButton:(UIButton *)sender{


}

//time stamp
-(NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath{

return nil;

}

-(CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath{

return 0;
}

#pragma mark - private functions
-(NSString *)defaultImageForGender:(NSString *)gender{

if([gender isEqualToString:@"M"] || [gender isEqualToString:@""]){
return @"no_image_male";
}else{
return @"no_image_female";
}
}

-(void)setNavigationBarTitleView{

UIView *whole = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width - 100, 100)];

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(5, 20, 50, 50)];

[imageView.layer setCornerRadius:25.0f];
[imageView setClipsToBounds:YES];
[imageView setContentMode:UIViewContentModeScaleAspectFill];

if([self.friendUserDetails.userDetails.profile_pic isEqualToString:@""] || [self.friendUserDetails.userDetails.profile_pic isEqual:[NSNull null]]){

if([self.friendUserDetails.userDetails.gender isEqualToString:@"M"]){
[imageView setImage:[UIImage imageNamed:@"no_image_male"]];
}else{
[imageView setImage:[UIImage imageNamed:@"no_image_female"]];
}
}else{

[imageView sd_setImageWithURL:[NSURL URLWithString:self.friendUserDetails.userDetails.profile_pic]];
}


UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 20, [UIScreen mainScreen].bounds.size.width, 50)];
[nameLabel setText:self.friendUserDetails.userDetails.fname];

[whole addSubview:nameLabel];
[whole addSubview:imageView];

self.navigationItem.titleView = whole;
}

#pragma mark - Avtar images area

-(void)avatarImagesForUrlString:(NSString *)urlString andOnCompletion:(void(^)(UIImage *image))completion{

if([urlString isEqualToString:@""] || [urlString isEqual:[NSNull null]]){

completion(nil);

}else{

[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:urlString] options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {

completion ([self cropAvatarImages:image]);
}];
}
}

-(UIImage *)cropAvatarImages:(UIImage *)image{

if(image){
return [JSQMessagesAvatarImageFactory circularAvatarImage:image withDiameter:48];
}else{
if([self.friendUserDetails.userDetails.gender isEqualToString:@"M"]){
return [UIImage imageNamed:@"no_image_male"];
}else{
return [UIImage imageNamed:@"no_image_female"];
}
}
}

#pragma mark - API calls

-(void)loadPreviousChatWithPageCount:(int)count{

[API fetchChatListOfUserWithParams:paramsDict andOnCompletion:^(NSDictionary *result, NSError *error){

if (!error) {

if ([[result objectForKey:@"status"] intValue]==1) {

NSArray *conversation_data = [result objectForKey:@"conversation_data"];
[messages removeAllObjects];
[conversation_data enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop){

JSQMessage *jsqMsg = [[JSQMessage alloc] initWithSenderId:obj[@"sender_id"] senderDisplayName:@"" date:obj[@"sent_date"] text:obj[@"message_content"]];

[messages insertObject:jsqMsg atIndex:idx];

}];
[self.collectionView reloadData];

}else{
[Neo_Constants showAlert:@"Error" Message:[result objectForKey:@"message"]];
}

}else{
[Neo_Constants showAlert:@"Error" Message:[error localizedDescription]];
}


}];

}

-(void)didPressSendButton:(UIButton *)button withMessageText:(NSString *)text senderId:(NSString *)senderId senderDisplayName:(NSString *)senderDisplayName date:(NSDate *)date{

// [JSQSystemSoundPlayer jsq_playMessageSentSound];

[API sendMessageFromUserWithParams:paramsDict andOnCompletion:^(NSDictionary *result, NSError *error){

if (!error) {

if ([[result objectForKey:@"status"] intValue]==1) {

[self loadPreviousChatWithPageCount:0];
[self.inputToolbar.contentView.textView setText:@""];

}else{
[Neo_Constants showAlert:@"Error" Message:[result objectForKey:@"message"]];
}

}else{
[Neo_Constants showAlert:@"Error" Message:[error localizedDescription]];
}


}];

}

@end

Answer

problem is in this code you initialise outgoing and incomming with the same method which is

outgoingMessagesBubbleImageWithColor

try incoming with

incomingMessagesBubbleImageWithColor

and outgoing with this

outgoingMessagesBubbleImageWithColor

this correct one

-(void)setupBubbles{
    JSQMessagesBubbleImageFactory *bubbleImageFactory = [JSQMessagesBubbleImageFactory new];

    outgoingBubbleImageView = [bubbleImageFactory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleBlueColor]];

    incomingBubbleImageView = [bubbleImageFactory incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleGreenColor]];

}