JSQMessagesViewController/JSQMessagesDemo/JSQDemoViewController.m
2014-04-23 21:36:18 -07:00

298 lines
13 KiB
Objective-C

//
// Created by Jesse Squires
// http://www.hexedbits.com
//
//
// Documentation
// http://cocoadocs.org/docsets/JSMessagesViewController
//
//
// The MIT License
// Copyright (c) 2014 Jesse Squires
// http://opensource.org/licenses/MIT
//
#import "JSQDemoViewController.h"
static NSString * const kJSQDemoAvatarNameCook = @"Tim Cook";
static NSString * const kJSQDemoAvatarNameJobs = @"Jobs";
static NSString * const kJSQDemoAvatarNameWoz = @"Steve Wozniak";
@interface JSQDemoViewController ()
@property (strong, nonatomic) UIImageView *outgoingBubbleImageView;
@property (strong, nonatomic) UIImageView *incomingBubbleImageView;
- (void)jsqDemo_setupTestModel;
@end
@implementation JSQDemoViewController
#pragma mark - Demo setup
- (void)jsqDemo_setupTestModel
{
/**
* Load some fake messages
*/
self.messages = [[NSMutableArray alloc] initWithObjects:
[[JSQMessage alloc] initWithText:@"Welcome to JSQMessages: A messaging UI framework for iOS." sender:self.sender date:[NSDate distantPast]],
[[JSQMessage alloc] initWithText:@"It is simple, elegant, and easy to use. There are super sweet default settings, but you can customize like crazy." sender:kJSQDemoAvatarNameWoz date:[NSDate distantPast]],
[[JSQMessage alloc] initWithText:@"It even has data detectors. You can call me tonight. My cell number is 123-456-7890. My website is www.hexedbits.com." sender:self.sender date:[NSDate distantPast]],
[[JSQMessage alloc] initWithText:@"JSQMessagesViewController is nearly an exact replica of the iOS Messages App. And perhaps, better." sender:kJSQDemoAvatarNameJobs date:[NSDate date]],
[[JSQMessage alloc] initWithText:@"It is unit-tested, free, and open-source." sender:kJSQDemoAvatarNameCook date:[NSDate date]],
[[JSQMessage alloc] initWithText:@"Oh, and there's sweet documentation." sender:self.sender date:[NSDate date]],
nil];
/**
* Create avatar images once and save
*/
CGFloat outgoingDiameter = self.collectionView.collectionViewLayout.outgoingAvatarViewSize.width;
UIImage *jsqImage = [JSQMessagesAvatarFactory avatarWithUserInitials:@"JSQ"
backgroundColor:[UIColor colorWithWhite:0.85f alpha:1.0f]
textColor:[UIColor colorWithWhite:0.60f alpha:1.0f]
font:[UIFont systemFontOfSize:14.0f]
diameter:outgoingDiameter];
CGFloat incomingDiameter = self.collectionView.collectionViewLayout.incomingAvatarViewSize.width;
UIImage *cookImage = [JSQMessagesAvatarFactory avatarWithImage:[UIImage imageNamed:@"demo_avatar_cook"]
diameter:incomingDiameter];
UIImage *jobsImage = [JSQMessagesAvatarFactory avatarWithImage:[UIImage imageNamed:@"demo_avatar_jobs"]
diameter:incomingDiameter];
UIImage *wozImage = [JSQMessagesAvatarFactory avatarWithImage:[UIImage imageNamed:@"demo_avatar_woz"]
diameter:incomingDiameter];
self.avatars = @{ self.sender : jsqImage,
kJSQDemoAvatarNameCook : cookImage,
kJSQDemoAvatarNameJobs : jobsImage,
kJSQDemoAvatarNameWoz : wozImage };
/**
* Change to add more messages for testing
*/
NSUInteger messagesToAdd = 0;
NSArray *copyOfMessages = [self.messages copy];
for (NSUInteger i = 0; i < messagesToAdd; i++) {
[self.messages addObjectsFromArray:copyOfMessages];
}
/**
* Change to YES to add a super long message for testing
* You should see "END" twice
*/
BOOL addREALLYLongMessage = NO;
if (addREALLYLongMessage) {
JSQMessage *reallyLongMessage = [JSQMessage messageWithText:@"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? END Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? END" sender:self.sender];
[self.messages addObject:reallyLongMessage];
}
}
#pragma mark - View lifecycle
/**
* Override point for customization
*/
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"JSQMessages";
self.sender = @"Jesse Squires";
self.inputToolbar.contentView.textView.placeHolder = NSLocalizedString(@"Message", nil);
[self jsqDemo_setupTestModel];
/**
* Create bubble images once and save
*/
self.outgoingBubbleImageView = [JSQMessagesBubbleImageFactory
outgoingMessageBubbleImageViewWithColor:[UIColor jsq_messageBubbleBlueColor]];
self.incomingBubbleImageView = [JSQMessagesBubbleImageFactory
incomingMessageBubbleImageViewWithColor:[UIColor jsq_messageBubbleLightGrayColor]];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Test Msg"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(receiveMessagePressed:)];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.delegateModal) {
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
target:self
action:@selector(closePressed:)];
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
/**
* Enable/disable springy bubbles, default is YES.
* For best results, toggle from `viewDidAppear:`
*/
self.collectionView.collectionViewLayout.springinessEnabled = YES;
}
#pragma mark - Actions
- (void)receiveMessagePressed:(UIBarButtonItem *)sender
{
self.showTypingIndicator = !self.showTypingIndicator;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
JSQMessage *copyMessage = [[self.messages lastObject] copy];
if (!copyMessage) {
return;
}
NSMutableArray *copyAvatars = [[self.avatars allKeys] mutableCopy];
[copyAvatars removeObject:self.sender];
copyMessage.sender = [copyAvatars objectAtIndex:arc4random_uniform((int)[copyAvatars count])];
[JSQSystemSoundPlayer jsq_playMessageReceivedSound];
[self.messages addObject:copyMessage];
[self finishReceivingMessage];
});
}
- (void)closePressed:(UIBarButtonItem *)sender
{
[self.delegateModal didDismissJSQDemoViewController:self];
}
#pragma mark - JSQMessagesViewController method overrides
- (void)didPressSendButton:(UIButton *)sender withMessage:(JSQMessage *)message
{
[JSQSystemSoundPlayer jsq_playMessageSentSound];
[self.messages addObject:message];
[self finishSendingMessage];
}
- (void)didPressAccessoryButton:(UIButton *)sender
{
NSLog(@"Camera pressed!");
}
#pragma mark - JSQMessages CollectionView DataSource
- (id<JSQMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [self.messages objectAtIndex:indexPath.row];
}
- (UIImageView *)collectionView:(JSQMessagesCollectionView *)collectionView sender:(NSString *)sender bubbleImageViewForItemAtIndexPath:(NSIndexPath *)indexPath
{
/**
* Reuse created bubble images, but create new imageView to add to each cell
* Otherwise, each cell would be referencing the same imageView and bubbles would disappear from cells
*/
if ([sender isEqualToString:self.sender]) {
return [[UIImageView alloc] initWithImage:self.outgoingBubbleImageView.image
highlightedImage:self.outgoingBubbleImageView.highlightedImage];
}
return [[UIImageView alloc] initWithImage:self.incomingBubbleImageView.image
highlightedImage:self.incomingBubbleImageView.highlightedImage];
}
- (UIImageView *)collectionView:(JSQMessagesCollectionView *)collectionView sender:(NSString *)sender avatarImageViewForItemAtIndexPath:(NSIndexPath *)indexPath
{
/**
* Reuse created avatar images, but create new imageView to add to each cell
* Otherwise, each cell would be referencing the same imageView and avatars would disappear from cells
*/
UIImage *avatarImage = [self.avatars objectForKey:sender];
return [[UIImageView alloc] initWithImage:avatarImage];
}
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView sender:(NSString *)sender attributedTextForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.item % 3 == 0) {
JSQMessage *message = [self.messages objectAtIndex:indexPath.item];
return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date];
}
return nil;
}
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView sender:(NSString *)sender attributedTextForMessageBubbleTopLabelAtIndexPath:(NSIndexPath *)indexPath
{
return [[NSAttributedString alloc] initWithString:sender];
}
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView sender:(NSString *)sender attributedTextForCellBottomLabelAtIndexPath:(NSIndexPath *)indexPath
{
return nil;
}
#pragma mark - UICollectionView DataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.messages count];
}
- (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
/**
* Override point for customizing cells
*/
JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:collectionView cellForItemAtIndexPath:indexPath];
return cell;
}
#pragma mark - JSQMessages collection view flow layout delegate
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.item % 3 == 0) {
return kJSQMessagesCollectionViewCellLabelHeightDefault;
}
return 0.0f;
}
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForMessageBubbleTopLabelAtIndexPath:(NSIndexPath *)indexPath
{
return kJSQMessagesCollectionViewCellLabelHeightDefault;
}
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellBottomLabelAtIndexPath:(NSIndexPath *)indexPath
{
return 0.0f;
}
@end