mirror of
https://github.com/zhigang1992/MessagesTableViewController.git
synced 2026-03-29 07:38:35 +08:00
Added AvatarView to the awesome MessageTableView.
This commit is contained in:
@@ -36,17 +36,22 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "JSBubbleView.h"
|
||||
|
||||
#define DATE_LABEL_HEIGHT 12.0f
|
||||
#define DATE_LABEL_HEIGHT 12.0f
|
||||
#define PHOTO_EDGE_INSET (UIEdgeInsets){2,4,2,4}
|
||||
#define PHOTO_SIZE (CGSize){40,40}
|
||||
|
||||
@interface JSBubbleMessageCell : UITableViewCell
|
||||
|
||||
#pragma mark - Initialization
|
||||
- (id)initWithBubbleStyle:(JSBubbleMessageStyle)style
|
||||
hasTimestamp:(BOOL)hasTimestamp
|
||||
hasAvatar:(BOOL)hasAvatar
|
||||
reuseIdentifier:(NSString *)reuseIdentifier;
|
||||
|
||||
#pragma mark - Message Cell
|
||||
- (void)setMessage:(NSString *)msg;
|
||||
- (void)setTimestamp:(NSDate *)date;
|
||||
|
||||
@property (strong, readonly) UIImageView *photoView;
|
||||
|
||||
@end
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
@property (strong, nonatomic) JSBubbleView *bubbleView;
|
||||
@property (strong, nonatomic) UILabel *timestampLabel;
|
||||
@property (strong, nonatomic) UIImageView *photoView;
|
||||
|
||||
- (void)setup;
|
||||
- (void)configureTimestampLabel;
|
||||
@@ -85,7 +86,7 @@
|
||||
[self.contentView bringSubviewToFront:self.timestampLabel];
|
||||
}
|
||||
|
||||
- (void)configureWithStyle:(JSBubbleMessageStyle)style timestamp:(BOOL)hasTimestamp
|
||||
- (void)configureWithStyle:(JSBubbleMessageStyle)style timestamp:(BOOL)hasTimestamp avatar:(BOOL)hasAvatar
|
||||
{
|
||||
CGFloat bubbleY = 0.0f;
|
||||
|
||||
@@ -94,9 +95,28 @@
|
||||
bubbleY = 14.0f;
|
||||
}
|
||||
|
||||
CGRect frame = CGRectMake(0.0f,
|
||||
CGFloat rightOffsetX=0.0f;
|
||||
CGFloat leftOffsetX=0.0f;
|
||||
|
||||
|
||||
|
||||
if(hasAvatar){
|
||||
|
||||
if(style==JSBubbleMessageStyleIncomingDefault||style==JSBubbleMessageStyleIncomingSquare){
|
||||
rightOffsetX=PHOTO_EDGE_INSET.left+PHOTO_SIZE.width+PHOTO_EDGE_INSET.right;
|
||||
self.photoView=[[UIImageView alloc] initWithFrame:(CGRect){PHOTO_EDGE_INSET.left,self.contentView.frame.size.height-PHOTO_EDGE_INSET.bottom-PHOTO_SIZE.height,PHOTO_SIZE}];
|
||||
}else{
|
||||
leftOffsetX=PHOTO_EDGE_INSET.left+PHOTO_SIZE.width+PHOTO_EDGE_INSET.right;
|
||||
self.photoView=[[UIImageView alloc] initWithFrame:(CGRect){self.contentView.frame.size.width-PHOTO_EDGE_INSET.right-PHOTO_SIZE.width,self.contentView.frame.size.height-PHOTO_EDGE_INSET.bottom-PHOTO_SIZE.height,PHOTO_SIZE}];
|
||||
}
|
||||
[self.contentView addSubview:self.photoView];
|
||||
self.photoView.autoresizingMask= (UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin);
|
||||
}
|
||||
|
||||
|
||||
CGRect frame = CGRectMake(rightOffsetX,
|
||||
bubbleY,
|
||||
self.contentView.frame.size.width,
|
||||
self.contentView.frame.size.width-rightOffsetX-leftOffsetX,
|
||||
self.contentView.frame.size.height - self.timestampLabel.frame.size.height);
|
||||
|
||||
self.bubbleView = [[JSBubbleView alloc] initWithFrame:frame
|
||||
@@ -108,12 +128,12 @@
|
||||
[self.contentView sendSubviewToBack:self.bubbleView];
|
||||
}
|
||||
|
||||
- (id)initWithBubbleStyle:(JSBubbleMessageStyle)style hasTimestamp:(BOOL)hasTimestamp reuseIdentifier:(NSString *)reuseIdentifier
|
||||
- (id)initWithBubbleStyle:(JSBubbleMessageStyle)style hasTimestamp:(BOOL)hasTimestamp hasAvatar:(BOOL)hasAvatar reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
|
||||
if(self) {
|
||||
[self setup];
|
||||
[self configureWithStyle:style timestamp:hasTimestamp];
|
||||
[self configureWithStyle:style timestamp:hasTimestamp avatar:hasAvatar];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -56,14 +56,17 @@ typedef enum {
|
||||
- (JSBubbleMessageStyle)messageStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
|
||||
- (JSMessagesViewTimestampPolicy)timestampPolicyForMessagesView;
|
||||
- (BOOL)hasTimestampForRowAtIndexPath:(NSIndexPath *)indexPath;
|
||||
- (BOOL )hasPhotoForRowAtIndexPath:(NSIndexPath *)indexPath;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@protocol JSMessagesViewDataSource <NSObject>
|
||||
@optional
|
||||
- (NSDate *)timestampForRowAtIndexPath:(NSIndexPath *)indexPath;
|
||||
- (void)goCrazyWithYourAvatarImageView:(UIImageView *)avatarView;
|
||||
@required
|
||||
- (NSString *)textForRowAtIndexPath:(NSIndexPath *)indexPath;
|
||||
- (NSDate *)timestampForRowAtIndexPath:(NSIndexPath *)indexPath;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
{
|
||||
JSBubbleMessageStyle style = [self.delegate messageStyleForRowAtIndexPath:indexPath];
|
||||
BOOL hasTimestamp = [self shouldHaveTimestampForRowAtIndexPath:indexPath];
|
||||
BOOL hasAvatar = [self shouldHavePhotoForRowAtIndexPath:indexPath];
|
||||
|
||||
NSString *CellID = [NSString stringWithFormat:@"MessageCell_%d_%d", style, hasTimestamp];
|
||||
JSBubbleMessageCell *cell = (JSBubbleMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellID];
|
||||
@@ -178,12 +179,17 @@
|
||||
if(!cell) {
|
||||
cell = [[JSBubbleMessageCell alloc] initWithBubbleStyle:style
|
||||
hasTimestamp:hasTimestamp
|
||||
hasAvatar:hasAvatar
|
||||
reuseIdentifier:CellID];
|
||||
}
|
||||
|
||||
if(hasTimestamp)
|
||||
[cell setTimestamp:[self.dataSource timestampForRowAtIndexPath:indexPath]];
|
||||
|
||||
if (hasAvatar) {
|
||||
[self.dataSource goCrazyWithYourAvatarImageView:cell.photoView];
|
||||
}
|
||||
|
||||
[cell setMessage:[self.dataSource textForRowAtIndexPath:indexPath]];
|
||||
[cell setBackgroundColor:tableView.backgroundColor];
|
||||
|
||||
@@ -194,8 +200,8 @@
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CGFloat dateHeight = [self shouldHaveTimestampForRowAtIndexPath:indexPath] ? DATE_LABEL_HEIGHT : 0.0f;
|
||||
|
||||
return [JSBubbleView cellHeightForText:[self.dataSource textForRowAtIndexPath:indexPath]] + dateHeight;
|
||||
CGFloat avatarCellHeight = [self shouldHavePhotoForRowAtIndexPath:indexPath] ? (PHOTO_SIZE.height + PHOTO_EDGE_INSET.top + PHOTO_EDGE_INSET.bottom) : 0.0f;
|
||||
return MAX(avatarCellHeight, [JSBubbleView cellHeightForText:[self.dataSource textForRowAtIndexPath:indexPath]] + dateHeight);
|
||||
}
|
||||
|
||||
#pragma mark - Messages view controller
|
||||
@@ -226,6 +232,14 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)shouldHavePhotoForRowAtIndexPath:(NSIndexPath *)indexPath{
|
||||
if ([self.delegate respondsToSelector:@selector(hasPhotoForRowAtIndexPath:)]) {
|
||||
return [self.delegate hasPhotoForRowAtIndexPath:indexPath];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)finishSend
|
||||
{
|
||||
[self.inputView.textView setText:nil];
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
04E5799817A0F65C0022CD77 /* DemoAvatarExample.png in Resources */ = {isa = PBXBuildFile; fileRef = 04E5799717A0F65C0022CD77 /* DemoAvatarExample.png */; };
|
||||
881AE55D16D13CDC008F7636 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 881AE55C16D13CDC008F7636 /* UIKit.framework */; };
|
||||
881AE55F16D13CDC008F7636 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 881AE55E16D13CDC008F7636 /* Foundation.framework */; };
|
||||
881AE56116D13CDC008F7636 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 881AE56016D13CDC008F7636 /* CoreGraphics.framework */; };
|
||||
@@ -54,6 +55,7 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
04E5799717A0F65C0022CD77 /* DemoAvatarExample.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DemoAvatarExample.png; sourceTree = "<group>"; };
|
||||
881AE55916D13CDC008F7636 /* MessagesDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MessagesDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
881AE55C16D13CDC008F7636 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
881AE55E16D13CDC008F7636 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
@@ -164,6 +166,7 @@
|
||||
881AE56C16D13CDC008F7636 /* AppDelegate.m */,
|
||||
881AE58216D13DE0008F7636 /* DemoViewController.h */,
|
||||
881AE58316D13DE0008F7636 /* DemoViewController.m */,
|
||||
04E5799717A0F65C0022CD77 /* DemoAvatarExample.png */,
|
||||
88301EE416F77B3D0037524D /* JSMessagesTableViewController */,
|
||||
881AE56316D13CDC008F7636 /* Supporting Files */,
|
||||
);
|
||||
@@ -337,6 +340,7 @@
|
||||
88244C0616FE5BA400034667 /* bubbleSquareIncoming@2x.png in Resources */,
|
||||
88244C0716FE5BA400034667 /* bubbleSquareOutgoing.png in Resources */,
|
||||
88244C0816FE5BA400034667 /* bubbleSquareOutgoing@2x.png in Resources */,
|
||||
04E5799817A0F65C0022CD77 /* DemoAvatarExample.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
BIN
MessagesDemo/DemoAvatarExample.png
Normal file
BIN
MessagesDemo/DemoAvatarExample.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
@@ -53,10 +53,10 @@
|
||||
self.title = @"Messages";
|
||||
|
||||
self.messages = [[NSMutableArray alloc] initWithObjects:
|
||||
@"Testing some messages here.",
|
||||
@"This work is based on Sam Soffes' SSMessagesViewController.",
|
||||
@"This is a complete re-write and refactoring.",
|
||||
@"It's easy to implement. Sound effects and images included. Animations are smooth and messages can be of arbitrary size!",
|
||||
@"Testing some here.",
|
||||
@"This workMessagesViewController.",
|
||||
@"Thcomplite and refactoring.",
|
||||
@"It'sffects and images included. Animations are smooth and messages can be of arbitrary size!",
|
||||
nil];
|
||||
|
||||
self.timestamps = [[NSMutableArray alloc] initWithObjects:
|
||||
@@ -104,6 +104,10 @@
|
||||
return [self shouldHaveTimestampForRowAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (BOOL)hasPhotoForRowAtIndexPath:(NSIndexPath *)indexPath{
|
||||
return (indexPath.row % 2);
|
||||
}
|
||||
|
||||
#pragma mark - Messages view data source
|
||||
- (NSString *)textForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
@@ -115,4 +119,8 @@
|
||||
return [self.timestamps objectAtIndex:indexPath.row];
|
||||
}
|
||||
|
||||
- (void)goCrazyWithYourAvatarImageView:(UIImageView *)avatarView{
|
||||
avatarView.image = [UIImage imageNamed:@"DemoAvatarExample"];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user