Skip to content
This repository was archived by the owner on Mar 9, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added example/Default-568h@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 32 additions & 5 deletions example/UIBubbleTableViewExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
20489A9519235BF9002CFE85 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 20489A9419235BF9002CFE85 /* Default-568h@2x.png */; };
20489A9819236065002CFE85 /* ImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 20489A9719236065002CFE85 /* ImageCache.m */; };
76687AFD1622039C00707588 /* UIBubbleTypingTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 76687AFC1622039C00707588 /* UIBubbleTypingTableViewCell.m */; };
76687AFF162203AF00707588 /* halloween.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 76687AFE162203AF00707588 /* halloween.jpg */; };
76D097CC1621F0E000C17816 /* UIBubbleHeaderTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 76D097CB1621F0E000C17816 /* UIBubbleHeaderTableViewCell.m */; };
Expand Down Expand Up @@ -37,6 +39,9 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
20489A9419235BF9002CFE85 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
20489A9619236065002CFE85 /* ImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ImageCache.h; path = ../../src/ImageCache.h; sourceTree = "<group>"; };
20489A9719236065002CFE85 /* ImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ImageCache.m; path = ../../src/ImageCache.m; sourceTree = "<group>"; };
76687AFB1622039C00707588 /* UIBubbleTypingTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UIBubbleTypingTableViewCell.h; path = ../../src/UIBubbleTypingTableViewCell.h; sourceTree = "<group>"; };
76687AFC1622039C00707588 /* UIBubbleTypingTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UIBubbleTypingTableViewCell.m; path = ../../src/UIBubbleTypingTableViewCell.m; sourceTree = "<group>"; };
76687AFE162203AF00707588 /* halloween.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = halloween.jpg; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -94,6 +99,7 @@
76ED205315BF096C00E186D3 = {
isa = PBXGroup;
children = (
20489A9419235BF9002CFE85 /* Default-568h@2x.png */,
76ED206815BF096C00E186D3 /* UIBubbleTableViewExample */,
76ED206115BF096C00E186D3 /* Frameworks */,
76ED205F15BF096C00E186D3 /* Products */,
Expand Down Expand Up @@ -151,6 +157,8 @@
76ED208315BF09AD00E186D3 /* src */ = {
isa = PBXGroup;
children = (
20489A9619236065002CFE85 /* ImageCache.h */,
20489A9719236065002CFE85 /* ImageCache.m */,
76ED208915BF0BB100E186D3 /* NSBubbleData.h */,
76ED208A15BF0BB100E186D3 /* NSBubbleData.m */,
76ED208515BF09E300E186D3 /* UIBubbleTableView.h */,
Expand Down Expand Up @@ -210,7 +218,7 @@
76ED205515BF096C00E186D3 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0430;
LastUpgradeCheck = 0510;
};
buildConfigurationList = 76ED205815BF096C00E186D3 /* Build configuration list for PBXProject "UIBubbleTableViewExample" */;
compatibilityVersion = "Xcode 3.2";
Expand Down Expand Up @@ -242,6 +250,7 @@
C83B107A15DE43180067DADE /* bubbleMine@2x.png in Resources */,
C83B107B15DE43180067DADE /* bubbleSomeone.png in Resources */,
C83B107C15DE43180067DADE /* bubbleSomeone@2x.png in Resources */,
20489A9519235BF9002CFE85 /* Default-568h@2x.png in Resources */,
C83B107D15DE43180067DADE /* typingMine.png in Resources */,
C83B107E15DE43180067DADE /* typingMine@2x.png in Resources */,
C83B107F15DE43180067DADE /* typingSomeone.png in Resources */,
Expand All @@ -267,6 +276,7 @@
76ED208B15BF0BB100E186D3 /* NSBubbleData.m in Sources */,
76ED209415BF29EE00E186D3 /* UIBubbleTableViewCell.m in Sources */,
76D097CC1621F0E000C17816 /* UIBubbleHeaderTableViewCell.m in Sources */,
20489A9819236065002CFE85 /* ImageCache.m in Sources */,
76687AFD1622039C00707588 /* UIBubbleTypingTableViewCell.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -297,7 +307,12 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
Expand All @@ -309,10 +324,14 @@
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
Expand All @@ -321,15 +340,23 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
Expand Down
2 changes: 1 addition & 1 deletion example/UIBubbleTableViewExample/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface

#pragma mark - UIBubbleTableViewDataSource implementation

- (NSInteger)rowsForBubbleTable:(UIBubbleTableView *)tableView
- (NSUInteger)rowsForBubbleTable:(UIBubbleTableView *)tableView
{
return [bubbleData count];
}
Expand Down
24 changes: 24 additions & 0 deletions src/ImageCache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// ImageCache.h
// InstrumentsTutorial
//
// Created by Matt Galloway on 06/09/2012.
// Copyright (c) 2012 Swipe Stack Ltd. All rights reserved.
// Modified by Lubos Ilcik on 14/05/2014.
//

#import <Foundation/Foundation.h>

typedef void(^ImageCacheDownloadCompletionHandler)(UIImage *image);

@interface ImageCache : NSObject

+ (id)sharedInstance;

- (UIImage*)imageForKey:(NSString*)key;
- (void)setImage:(UIImage*)image forKey:(NSString*)key;
- (void)downloadImageAtURL:(NSURL*)url completionHandler:(ImageCacheDownloadCompletionHandler)completion;
- (UIImage*)imageNamed:(NSString*)name;
- (UIImage *)imageNamed:(NSString*)name stretchableWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;

@end
84 changes: 84 additions & 0 deletions src/ImageCache.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// ImageCache.m
// InstrumentsTutorial
//
// Created by Matt Galloway on 06/09/2012.
// Copyright (c) 2012 Swipe Stack Ltd. All rights reserved.
// Modified by Lubos Ilcik on 14/05/2014.
//

#import "ImageCache.h"

@interface ImageCache () {
NSMutableDictionary *_cache;
}
@end

@implementation ImageCache

+ (id)sharedInstance {
static ImageCache *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[[self class] alloc] init];
});
return sharedInstance;
}

- (id)init {
if ((self = [super init])) {
_cache = [NSMutableDictionary new];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(memoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
}
return self;
}

- (UIImage*)imageForKey:(NSString*)key {
return [_cache objectForKey:key];
}

- (void)setImage:(UIImage*)image forKey:(NSString*)key {
[_cache setObject:image forKey:key];
}

- (void)downloadImageAtURL:(NSURL*)url completionHandler:(ImageCacheDownloadCompletionHandler)completion {
UIImage *cachedImage = [self imageForKey:[url absoluteString]];
if (cachedImage) {
completion(cachedImage);
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
[self setImage:image forKey:[url absoluteString]];
dispatch_async(dispatch_get_main_queue(), ^{
completion(image);
});
});
}
}

- (UIImage*)imageNamed:(NSString*)name {
UIImage *image;
if (!(image = [self imageForKey:name])) {
image = [UIImage imageNamed:name];
[self setImage:image forKey:name];
}
return image;
}

- (UIImage *)imageNamed:(NSString*)name stretchableWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight {
UIImage *image;
if (!(image = [self imageForKey:name])) {
image = [[UIImage imageNamed:name] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];
[self setImage:image forKey:name];
}
return image;
}

#pragma mark - Private

- (void)memoryWarning:(NSNotification*)note {
[_cache removeAllObjects];
}

@end
11 changes: 8 additions & 3 deletions src/NSBubbleData.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,14 @@ + (id)dataWithText:(NSString *)text date:(NSDate *)date type:(NSBubbleType)type
- (id)initWithText:(NSString *)text date:(NSDate *)date type:(NSBubbleType)type
{
UIFont *font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
CGSize size = [(text ? text : @"") sizeWithFont:font constrainedToSize:CGSizeMake(220, 9999) lineBreakMode:NSLineBreakByWordWrapping];

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
CGSize size = [(text ? text : @"") boundingRectWithSize: CGSizeMake(220, 9999) options: NSStringDrawingUsesLineFragmentOrigin attributes: @{ NSFontAttributeName:font }context: nil].size;
/*
documention mentions
"In iOS 7 and later, this method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function."
*/
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, height)];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text = (text ? text : @"");
Expand Down
1 change: 1 addition & 0 deletions src/UIBubbleHeaderTableViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ - (void)setDate:(NSDate *)value
self.label.shadowColor = [UIColor whiteColor];
self.label.textColor = [UIColor darkGrayColor];
self.label.backgroundColor = [UIColor clearColor];
self.label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self addSubview:self.label];
}

Expand Down
25 changes: 16 additions & 9 deletions src/UIBubbleTableView.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#import "UIBubbleHeaderTableViewCell.h"
#import "UIBubbleTypingTableViewCell.h"

static NSString * const kBubbleTypingCell = @"tblBubbleTypingCell";
static NSString * const kBubbleHeaderCell = @"tblBubbleHeaderCell";
static NSString * const kBubbleCell = @"tblBubbleCell";

@interface UIBubbleTableView ()

@property (nonatomic, retain) NSMutableArray *bubbleSection;
Expand Down Expand Up @@ -44,6 +48,12 @@ - (void)initializator

self.snapInterval = 120;
self.typingBubble = NSBubbleTypingTypeNobody;

// cell class must be registered otherwise dequeueReusableCellWithIdentifier: returns nill!
[self registerClass:[UIBubbleTableViewCell class] forCellReuseIdentifier:kBubbleCell];
[self registerClass:[UIBubbleHeaderTableViewCell class] forCellReuseIdentifier:kBubbleHeaderCell];
[self registerClass:[UIBubbleTypingTableViewCell class] forCellReuseIdentifier:kBubbleTypingCell];

}

- (id)init
Expand Down Expand Up @@ -95,7 +105,7 @@ - (void)reloadData
self.bubbleSection = nil;

// Loading new data
int count = 0;
NSUInteger count = 0;
#if !__has_feature(objc_arc)
self.bubbleSection = [[[NSMutableArray alloc] init] autorelease];
#else
Expand Down Expand Up @@ -156,7 +166,7 @@ - (void)reloadData

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
int result = [self.bubbleSection count];
NSInteger result = [self.bubbleSection count];
if (self.typingBubble != NSBubbleTypingTypeNobody) result++;
return result;
}
Expand All @@ -169,7 +179,7 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger
return [[self.bubbleSection objectAtIndex:section] count] + 1;
}

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Now typing
if (indexPath.section >= [self.bubbleSection count])
Expand All @@ -192,8 +202,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
// Now typing
if (indexPath.section >= [self.bubbleSection count])
{
static NSString *cellId = @"tblBubbleTypingCell";
UIBubbleTypingTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
UIBubbleTypingTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kBubbleTypingCell];

if (cell == nil) cell = [[UIBubbleTypingTableViewCell alloc] init];

Expand All @@ -206,8 +215,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
// Header with date and time
if (indexPath.row == 0)
{
static NSString *cellId = @"tblBubbleHeaderCell";
UIBubbleHeaderTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
UIBubbleHeaderTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kBubbleHeaderCell];
NSBubbleData *data = [[self.bubbleSection objectAtIndex:indexPath.section] objectAtIndex:0];

if (cell == nil) cell = [[UIBubbleHeaderTableViewCell alloc] init];
Expand All @@ -218,8 +226,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
}

// Standard bubble
static NSString *cellId = @"tblBubbleCell";
UIBubbleTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
UIBubbleTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kBubbleCell];
NSBubbleData *data = [[self.bubbleSection objectAtIndex:indexPath.section] objectAtIndex:indexPath.row - 1];

if (cell == nil) cell = [[UIBubbleTableViewCell alloc] init];
Expand Down
Loading