This repository has been archived by the owner on Aug 14, 2019. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
679ac60
commit 983fb58
Showing
7 changed files
with
284 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
JSQMessagesViewController/Layout/JSQMessagesBubbleSizeCalculating.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// | ||
// Created by Jesse Squires | ||
// http://www.jessesquires.com | ||
// | ||
// | ||
// Documentation | ||
// http://cocoadocs.org/docsets/JSQMessagesViewController | ||
// | ||
// | ||
// GitHub | ||
// https://github.com/jessesquires/JSQMessagesViewController | ||
// | ||
// | ||
// License | ||
// Copyright (c) 2014 Jesse Squires | ||
// Released under an MIT license: http://opensource.org/licenses/MIT | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
#import <UIKit/UIKit.h> | ||
|
||
@class JSQMessagesCollectionViewFlowLayout; | ||
@protocol JSQMessageData; | ||
|
||
/** | ||
* The `JSQMessagesBubbleSizeCalculating` protocol defines the common interface through which | ||
* an object provides layout information to an instance of `JSQMessagesCollectionViewFlowLayout`. | ||
* | ||
* A concrete class that conforms to this protocol is provided in the library. | ||
* See `JSQMessagesBubbleSizeCalculator`. | ||
*/ | ||
@protocol JSQMessagesBubbleSizeCalculating <NSObject> | ||
|
||
/** | ||
* Computes and returns the size of the `messageBubbleImageView` property | ||
* of a `JSQMessagesCollectionViewCell` for the specified messageData at indexPath. | ||
* | ||
* @param messageData A message data object. | ||
* @param indexPath The index path at which messageData is located. | ||
* @param layout The layout object asking for this information. | ||
* | ||
* @return A sizes that specifies the required dimensions to display the entire message contents. | ||
* Note, this is *not* the entire cell, but only its message bubble. | ||
*/ | ||
- (CGSize)messageBubbleSizeForMessageData:(id<JSQMessageData>)messageData | ||
atIndexPath:(NSIndexPath *)indexPath | ||
withLayout:(JSQMessagesCollectionViewFlowLayout *)layout; | ||
|
||
/** | ||
* Notifies the receiver that the layout will be reset. | ||
* Use this method to clear any cached layout information, if necessary. | ||
* | ||
* @param layout The layout object notifying the receiver. | ||
*/ | ||
- (void)prepareForResettingLayout:(JSQMessagesCollectionViewFlowLayout *)layout; | ||
|
||
@end |
40 changes: 40 additions & 0 deletions
40
JSQMessagesViewController/Layout/JSQMessagesBubblesSizeCalculator.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// | ||
// Created by Jesse Squires | ||
// http://www.jessesquires.com | ||
// | ||
// | ||
// Documentation | ||
// http://cocoadocs.org/docsets/JSQMessagesViewController | ||
// | ||
// | ||
// GitHub | ||
// https://github.com/jessesquires/JSQMessagesViewController | ||
// | ||
// | ||
// License | ||
// Copyright (c) 2014 Jesse Squires | ||
// Released under an MIT license: http://opensource.org/licenses/MIT | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
#import "JSQMessagesBubbleSizeCalculating.h" | ||
|
||
/** | ||
* An instance of `JSQMessagesBubblesSizeCalculator` is responsible for calculating | ||
* message bubble sizes for an instance of `JSQMessagesCollectionViewFlowLayout`. | ||
*/ | ||
@interface JSQMessagesBubblesSizeCalculator : NSObject <JSQMessagesBubbleSizeCalculating> | ||
|
||
/** | ||
* Initializes and returns a bubble size calculator with the given cache and minimumBubbleWidth. | ||
* | ||
* @param cache A cache object used to store layout information. | ||
* @param minimumBubbleWidth The minimum width for any given message bubble. | ||
* | ||
* @return An initialized `JSQMessagesBubblesSizeCalculator` object if successful, `nil` otherwise. | ||
*/ | ||
- (instancetype)initWithCache:(NSCache *)cache | ||
minimumBubbleWidth:(NSUInteger)minimumBubbleWidth NS_DESIGNATED_INITIALIZER; | ||
|
||
@end |
141 changes: 141 additions & 0 deletions
141
JSQMessagesViewController/Layout/JSQMessagesBubblesSizeCalculator.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
// | ||
// Created by Jesse Squires | ||
// http://www.jessesquires.com | ||
// | ||
// | ||
// Documentation | ||
// http://cocoadocs.org/docsets/JSQMessagesViewController | ||
// | ||
// | ||
// GitHub | ||
// https://github.com/jessesquires/JSQMessagesViewController | ||
// | ||
// | ||
// License | ||
// Copyright (c) 2014 Jesse Squires | ||
// Released under an MIT license: http://opensource.org/licenses/MIT | ||
// | ||
|
||
#import "JSQMessagesBubblesSizeCalculator.h" | ||
|
||
#import "JSQMessagesCollectionView.h" | ||
#import "JSQMessagesCollectionViewDataSource.h" | ||
#import "JSQMessagesCollectionViewFlowLayout.h" | ||
#import "JSQMessageData.h" | ||
|
||
#import "UIImage+JSQMessages.h" | ||
|
||
|
||
@interface JSQMessagesBubblesSizeCalculator () | ||
|
||
@property (strong, nonatomic, readonly) NSCache *cache; | ||
|
||
@property (assign, nonatomic, readonly) NSUInteger minimumBubbleWidth; | ||
|
||
@end | ||
|
||
|
||
@implementation JSQMessagesBubblesSizeCalculator | ||
|
||
#pragma mark - Init | ||
|
||
- (instancetype)initWithCache:(NSCache *)cache minimumBubbleWidth:(NSUInteger)minimumBubbleWidth | ||
{ | ||
NSParameterAssert(cache != nil); | ||
NSParameterAssert(minimumBubbleWidth > 0); | ||
|
||
self = [super init]; | ||
if (self) { | ||
_cache = cache; | ||
_minimumBubbleWidth = minimumBubbleWidth; | ||
} | ||
return self; | ||
} | ||
|
||
- (instancetype)init | ||
{ | ||
NSCache *cache = [NSCache new]; | ||
cache.name = @"JSQMessagesBubblesSizeCalculator.cache"; | ||
cache.countLimit = 200; | ||
return [self initWithCache:cache | ||
minimumBubbleWidth:[UIImage jsq_bubbleCompactImage].size.width]; | ||
} | ||
|
||
#pragma mark - NSObject | ||
|
||
- (NSString *)description | ||
{ | ||
return [NSString stringWithFormat:@"<%@: cache=%@, minimumBubbleWidth=%@>", | ||
[self class], self.cache, @(self.minimumBubbleWidth)]; | ||
} | ||
|
||
#pragma mark - JSQMessagesBubbleSizeCalculating | ||
|
||
- (void)prepareForResettingLayout:(JSQMessagesCollectionViewFlowLayout *)layout | ||
{ | ||
[self.cache removeAllObjects]; | ||
} | ||
|
||
- (CGSize)messageBubbleSizeForMessageData:(id<JSQMessageData>)messageData | ||
atIndexPath:(NSIndexPath *)indexPath | ||
withLayout:(JSQMessagesCollectionViewFlowLayout *)layout | ||
{ | ||
NSValue *cachedSize = [self.cache objectForKey:@([messageData messageHash])]; | ||
if (cachedSize != nil) { | ||
return [cachedSize CGSizeValue]; | ||
} | ||
|
||
CGSize finalSize = CGSizeZero; | ||
|
||
if ([messageData isMediaMessage]) { | ||
finalSize = [[messageData media] mediaViewDisplaySize]; | ||
} | ||
else { | ||
CGSize avatarSize = [self jsq_avatarSizeForMessageData:messageData withLayout:layout]; | ||
|
||
// from the cell xibs, there is a 2 point space between avatar and bubble | ||
CGFloat spacingBetweenAvatarAndBubble = 2.0f; | ||
CGFloat horizontalContainerInsets = layout.messageBubbleTextViewTextContainerInsets.left + layout.messageBubbleTextViewTextContainerInsets.right; | ||
CGFloat horizontalFrameInsets = layout.messageBubbleTextViewFrameInsets.left + layout.messageBubbleTextViewFrameInsets.right; | ||
|
||
CGFloat horizontalInsetsTotal = horizontalContainerInsets + horizontalFrameInsets + spacingBetweenAvatarAndBubble; | ||
CGFloat maximumTextWidth = layout.itemWidth - avatarSize.width - layout.messageBubbleLeftRightMargin - horizontalInsetsTotal; | ||
|
||
CGRect stringRect = [[messageData text] boundingRectWithSize:CGSizeMake(maximumTextWidth, CGFLOAT_MAX) | ||
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) | ||
attributes:@{ NSFontAttributeName : layout.messageBubbleFont } | ||
context:nil]; | ||
|
||
CGSize stringSize = CGRectIntegral(stringRect).size; | ||
|
||
CGFloat verticalContainerInsets = layout.messageBubbleTextViewTextContainerInsets.top + layout.messageBubbleTextViewTextContainerInsets.bottom; | ||
CGFloat verticalFrameInsets = layout.messageBubbleTextViewFrameInsets.top + layout.messageBubbleTextViewFrameInsets.bottom; | ||
|
||
// add extra 2 points of space, because `boundingRectWithSize:` is slightly off | ||
// not sure why. magix. (shrug) if you know, submit a PR | ||
CGFloat verticalInsets = verticalContainerInsets + verticalFrameInsets + 2.0f; | ||
|
||
// same as above, an extra 2 points of magix | ||
CGFloat finalWidth = MAX(stringSize.width + horizontalInsetsTotal, self.minimumBubbleWidth) + 2.0f; | ||
|
||
finalSize = CGSizeMake(finalWidth, stringSize.height + verticalInsets); | ||
} | ||
|
||
[self.cache setObject:[NSValue valueWithCGSize:finalSize] forKey:@([messageData messageHash])]; | ||
|
||
return finalSize; | ||
} | ||
|
||
- (CGSize)jsq_avatarSizeForMessageData:(id<JSQMessageData>)messageData | ||
withLayout:(JSQMessagesCollectionViewFlowLayout *)layout | ||
{ | ||
NSString *messageSender = [messageData senderId]; | ||
|
||
if ([messageSender isEqualToString:[layout.collectionView.dataSource senderId]]) { | ||
return layout.outgoingAvatarViewSize; | ||
} | ||
|
||
return layout.incomingAvatarViewSize; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.