Initial commit
This commit is contained in:
+142
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// AGEmojiKeyboardView.h
|
||||
// AGEmojiKeyboard
|
||||
//
|
||||
// Created by Ayush on 09/05/13.
|
||||
// Copyright (c) 2013 Ayush. All rights reserved.
|
||||
//
|
||||
// Set as inputView to textfields, this view class gives an
|
||||
// interface to the user to enter emoji characters.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, UMComEmojiKeyboardViewCategoryImage) {
|
||||
AGEmojiKeyboardViewCategoryImageFace,
|
||||
AGEmojiKeyboardViewCategoryImageBell,
|
||||
AGEmojiKeyboardViewCategoryImageFlower,
|
||||
AGEmojiKeyboardViewCategoryImageCar,
|
||||
AGEmojiKeyboardViewCategoryImageCharacters
|
||||
};
|
||||
|
||||
@protocol UMComEmojiKeyboardViewDelegate;
|
||||
@protocol AGEmojiKeyboardViewDataSource;
|
||||
|
||||
/**
|
||||
Keyboard class to present as an alternate.
|
||||
This keyboard presents the emojis supported by iOS.
|
||||
|
||||
@note To modify appearance, use @p segmentsBar @p pageControl
|
||||
@p emojiPagesScrollView properties.
|
||||
*/
|
||||
@interface UMComEmojiKeyboardView : UIView
|
||||
|
||||
/**
|
||||
Segment control displays the categories.
|
||||
*/
|
||||
@property (nonatomic, readonly) UISegmentedControl *segmentsBar;
|
||||
|
||||
/**
|
||||
Pagecontrol displays the current page and number of pages on an emoji page.
|
||||
*/
|
||||
@property (nonatomic, readonly) UIPageControl *pageControl;
|
||||
|
||||
/**
|
||||
Scroll view displays all the emoji pages.
|
||||
*/
|
||||
@property (nonatomic, readonly) UIScrollView *emojiPagesScrollView;
|
||||
|
||||
@property (nonatomic, weak) id<UMComEmojiKeyboardViewDelegate> delegate;
|
||||
@property (nonatomic, weak) id<AGEmojiKeyboardViewDataSource> dataSource;
|
||||
|
||||
/**
|
||||
@param frame Frame of the view to be initialised with.
|
||||
|
||||
@param dataSource dataSource is required during the initialization to
|
||||
get all the relevent images to present in the view.
|
||||
*/
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
dataSource:(id<AGEmojiKeyboardViewDataSource>)dataSource;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
Protocol to be followed by the dataSource of `AGEmojiKeyboardView`.
|
||||
*/
|
||||
@protocol AGEmojiKeyboardViewDataSource <NSObject>
|
||||
|
||||
/**
|
||||
Method called on dataSource to get the category image when selected.
|
||||
|
||||
@param emojiKeyBoardView EmojiKeyBoardView object on which user has tapped.
|
||||
|
||||
@param category category to get the image for. @see AGEmojiKeyboardViewCategoryImage
|
||||
*/
|
||||
- (UIImage *)emojiKeyboardView:(UMComEmojiKeyboardView *)emojiKeyboardView
|
||||
imageForSelectedCategory:(UMComEmojiKeyboardViewCategoryImage)category;
|
||||
|
||||
/**
|
||||
Method called on dataSource to get the category image when not-selected.
|
||||
|
||||
@param emojiKeyBoardView EmojiKeyBoardView object on which user has tapped.
|
||||
|
||||
@param category category to get the image for. @see AGEmojiKeyboardViewCategoryImage
|
||||
*/
|
||||
- (UIImage *)emojiKeyboardView:(UMComEmojiKeyboardView *)emojiKeyboardView
|
||||
imageForNonSelectedCategory:(UMComEmojiKeyboardViewCategoryImage)category;
|
||||
|
||||
/**
|
||||
Method called on dataSource to get the back button image to be shown in the view.
|
||||
|
||||
@param emojiKeyBoardView EmojiKeyBoardView object on which user has tapped.
|
||||
*/
|
||||
- (UIImage *)backSpaceButtonImageForEmojiKeyboardView:(UMComEmojiKeyboardView *)emojiKeyboardView;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Method called on dataSource to get category that should be shown by
|
||||
default i.e. when the keyboard is just presented.
|
||||
|
||||
@note By default `AGEmojiKeyboardViewCategoryImageRecent` is shown.
|
||||
|
||||
@param emojiKeyBoardView EmojiKeyBoardView object shown.
|
||||
*/
|
||||
- (UMComEmojiKeyboardViewCategoryImage)defaultCategoryForEmojiKeyboardView:(UMComEmojiKeyboardView *)emojiKeyboardView;
|
||||
|
||||
/**
|
||||
Method called on dataSource to get number of emojis to be maintained in
|
||||
recent category.
|
||||
|
||||
@note By default `50` is used.
|
||||
|
||||
@param emojiKeyBoardView EmojiKeyBoardView object shown.
|
||||
*/
|
||||
- (NSUInteger)recentEmojisMaintainedCountForEmojiKeyboardView:(UMComEmojiKeyboardView *)emojiKeyboardView;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
Protocol to be followed by the delegate of `AGEmojiKeyboardView`.
|
||||
*/
|
||||
@protocol UMComEmojiKeyboardViewDelegate <NSObject>
|
||||
|
||||
/**
|
||||
Delegate method called when user taps an emoji button
|
||||
|
||||
@param emojiKeyBoardView EmojiKeyBoardView object on which user has tapped.
|
||||
|
||||
@param emoji Emoji used by user
|
||||
*/
|
||||
- (void)emojiKeyBoardView:(UMComEmojiKeyboardView *)emojiKeyBoardView
|
||||
didUseEmoji:(NSString *)emoji;
|
||||
|
||||
/**
|
||||
Delegate method called when user taps on the backspace button
|
||||
|
||||
@param emojiKeyBoardView EmojiKeyBoardView object on which user has tapped.
|
||||
*/
|
||||
- (void)emojiKeyBoardViewDidPressBackSpace:(UMComEmojiKeyboardView *)emojiKeyBoardView;
|
||||
|
||||
@end
|
||||
+357
@@ -0,0 +1,357 @@
|
||||
//
|
||||
// AGEmojiKeyboardView.m
|
||||
// AGEmojiKeyboard
|
||||
//
|
||||
// Created by Ayush on 09/05/13.
|
||||
// Copyright (c) 2013 Ayush. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UMComEmojiKeyBoardView.h"
|
||||
#import "UMComEmojiPageView.h"
|
||||
#import "UMComResouceDefines.h"
|
||||
|
||||
static const CGFloat ButtonWidth = 53;
|
||||
static const CGFloat ButtonHeight = 50;
|
||||
|
||||
#define ColumnNum 7
|
||||
#define RowNum 3
|
||||
|
||||
static const NSUInteger DefaultRecentEmojisMaintainedCount = 50;
|
||||
|
||||
static NSString *const segmentRecentName = @"Recent";
|
||||
NSString *const RecentUsedEmojiCharactersKey = @"RecentUsedEmojiCharactersKey";
|
||||
|
||||
|
||||
@interface UMComEmojiKeyboardView () <UIScrollViewDelegate, AGEmojiPageViewDelegate>
|
||||
|
||||
@property (nonatomic) UISegmentedControl *segmentsBar;
|
||||
@property (nonatomic) UIPageControl *pageControl;
|
||||
@property (nonatomic) UIScrollView *emojiPagesScrollView;
|
||||
@property (nonatomic) NSMutableDictionary *emojis;
|
||||
@property (nonatomic) NSMutableArray *pageViews;
|
||||
@property (nonatomic) NSString *category;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UMComEmojiKeyboardView
|
||||
|
||||
- (NSDictionary *)emojis {
|
||||
if (!_emojis) {
|
||||
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"UMComSDKResources.bundle/EmojisList"
|
||||
ofType:@"plist"];
|
||||
NSDictionary *emojis = [NSDictionary dictionaryWithContentsOfFile:plistPath];
|
||||
NSString *emojiString = [emojis valueForKey:@"People"];
|
||||
|
||||
NSArray * emojisArray = [emojiString componentsSeparatedByString:@" "];
|
||||
_emojis = [NSMutableDictionary dictionaryWithObject:emojisArray forKey:@"People"];
|
||||
}
|
||||
return _emojis;
|
||||
}
|
||||
|
||||
- (NSString *)categoryNameAtIndex:(NSUInteger)index {
|
||||
NSArray *categoryList = @[@"People", @"Objects", @"Nature", @"Places", @"Symbols"];
|
||||
return categoryList[index];
|
||||
}
|
||||
|
||||
- (UMComEmojiKeyboardViewCategoryImage)defaultSelectedCategory {
|
||||
if ([self.dataSource respondsToSelector:@selector(defaultCategoryForEmojiKeyboardView:)]) {
|
||||
return [self.dataSource defaultCategoryForEmojiKeyboardView:self];
|
||||
}
|
||||
return AGEmojiKeyboardViewCategoryImageFace;
|
||||
}
|
||||
|
||||
- (NSUInteger)recentEmojisMaintainedCount {
|
||||
if ([self.dataSource respondsToSelector:@selector(recentEmojisMaintainedCountForEmojiKeyboardView:)]) {
|
||||
return [self.dataSource recentEmojisMaintainedCountForEmojiKeyboardView:self];
|
||||
}
|
||||
return DefaultRecentEmojisMaintainedCount;
|
||||
}
|
||||
|
||||
- (NSArray *)imagesForSelectedSegments {
|
||||
static NSMutableArray *array;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
array = [NSMutableArray array];
|
||||
for (UMComEmojiKeyboardViewCategoryImage i = AGEmojiKeyboardViewCategoryImageFace;
|
||||
i <= AGEmojiKeyboardViewCategoryImageCharacters;
|
||||
++i) {
|
||||
[array addObject:[self.dataSource emojiKeyboardView:self imageForSelectedCategory:i]];
|
||||
}
|
||||
});
|
||||
return array;
|
||||
}
|
||||
|
||||
- (NSArray *)imagesForNonSelectedSegments {
|
||||
static NSMutableArray *array;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
array = [NSMutableArray array];
|
||||
for (UMComEmojiKeyboardViewCategoryImage i = AGEmojiKeyboardViewCategoryImageFace;
|
||||
i <= AGEmojiKeyboardViewCategoryImageCharacters;
|
||||
++i) {
|
||||
[array addObject:[self.dataSource emojiKeyboardView:self imageForNonSelectedCategory:i]];
|
||||
}
|
||||
});
|
||||
return array;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame dataSource:(id<AGEmojiKeyboardViewDataSource>)dataSource {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
// initialize category
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
_dataSource = dataSource;
|
||||
|
||||
self.category = [self categoryNameAtIndex:self.defaultSelectedCategory];
|
||||
|
||||
self.pageControl = [[UIPageControl alloc] init];
|
||||
self.pageControl.hidesForSinglePage = YES;
|
||||
self.pageControl.currentPage = 0;
|
||||
self.pageControl.backgroundColor = [UIColor clearColor];
|
||||
CGSize pageControlSize = [self.pageControl sizeForNumberOfPages:3];
|
||||
CGSize frameSize = CGSizeMake(CGRectGetWidth(self.bounds),
|
||||
CGRectGetHeight(self.bounds) - pageControlSize.height);
|
||||
NSUInteger numberOfPages = [self numberOfPagesForCategory:self.category
|
||||
inFrameSize:frameSize];
|
||||
self.pageControl.numberOfPages = numberOfPages;
|
||||
// pageControlSize = [self.pageControl sizeForNumberOfPages:numberOfPages];
|
||||
CGRect pageControlFrame = CGRectMake((CGRectGetWidth(self.bounds) - pageControlSize.width) / 2,
|
||||
CGRectGetHeight(self.bounds) - pageControlSize.height,
|
||||
pageControlSize.width,
|
||||
pageControlSize.height);
|
||||
self.pageControl.frame = CGRectIntegral(pageControlFrame);
|
||||
[self.pageControl addTarget:self
|
||||
action:@selector(pageControlTouched:)
|
||||
forControlEvents:UIControlEventValueChanged];
|
||||
self.pageControl.currentPageIndicatorTintColor = [UIColor darkGrayColor];
|
||||
self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
|
||||
[self addSubview:self.pageControl];
|
||||
|
||||
CGRect scrollViewFrame = CGRectMake(0,
|
||||
CGRectGetHeight(self.segmentsBar.bounds),
|
||||
CGRectGetWidth(self.bounds),
|
||||
CGRectGetHeight(self.bounds) - CGRectGetHeight(self.segmentsBar.bounds) - pageControlSize.height);
|
||||
self.emojiPagesScrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
|
||||
self.emojiPagesScrollView.pagingEnabled = YES;
|
||||
self.emojiPagesScrollView.showsHorizontalScrollIndicator = NO;
|
||||
self.emojiPagesScrollView.showsVerticalScrollIndicator = NO;
|
||||
self.emojiPagesScrollView.delegate = self;
|
||||
|
||||
[self addSubview:self.emojiPagesScrollView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
CGSize pageControlSize = [self.pageControl sizeForNumberOfPages:3];
|
||||
NSUInteger numberOfPages = [self numberOfPagesForCategory:self.category
|
||||
inFrameSize:CGSizeMake(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - CGRectGetHeight(self.segmentsBar.bounds) - pageControlSize.height)];
|
||||
|
||||
NSInteger currentPage = (self.pageControl.currentPage > numberOfPages) ? numberOfPages : self.pageControl.currentPage;
|
||||
|
||||
// if (currentPage > numberOfPages) it is set implicitly to max pageNumber available
|
||||
self.pageControl.numberOfPages = numberOfPages;
|
||||
pageControlSize = [self.pageControl sizeForNumberOfPages:numberOfPages];
|
||||
CGRect pageControlFrame = CGRectMake((CGRectGetWidth(self.bounds) - pageControlSize.width) / 2,
|
||||
CGRectGetHeight(self.bounds) - pageControlSize.height,
|
||||
pageControlSize.width,
|
||||
pageControlSize.height);
|
||||
self.pageControl.frame = CGRectIntegral(pageControlFrame);
|
||||
|
||||
self.emojiPagesScrollView.frame = CGRectMake(0,
|
||||
CGRectGetHeight(self.segmentsBar.bounds),
|
||||
CGRectGetWidth(self.bounds),
|
||||
CGRectGetHeight(self.bounds) - CGRectGetHeight(self.segmentsBar.bounds) - pageControlSize.height);
|
||||
[self.emojiPagesScrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
self.emojiPagesScrollView.contentOffset = CGPointMake(CGRectGetWidth(self.emojiPagesScrollView.bounds) * currentPage, 0);
|
||||
self.emojiPagesScrollView.contentSize = CGSizeMake(CGRectGetWidth(self.emojiPagesScrollView.bounds) * numberOfPages,
|
||||
CGRectGetHeight(self.emojiPagesScrollView.bounds));
|
||||
[self purgePageViews];
|
||||
self.pageViews = [NSMutableArray array];
|
||||
[self setPage:currentPage];
|
||||
}
|
||||
|
||||
#pragma mark event handlers
|
||||
|
||||
- (void)setSelectedCategoryImageInSegmentControl:(UISegmentedControl *)segmentsBar
|
||||
atIndex:(NSInteger)index {
|
||||
for (int i=0; i < self.segmentsBar.numberOfSegments; ++i) {
|
||||
[segmentsBar setImage:self.imagesForNonSelectedSegments[i] forSegmentAtIndex:i];
|
||||
}
|
||||
[segmentsBar setImage:self.imagesForSelectedSegments[index] forSegmentAtIndex:index];
|
||||
}
|
||||
|
||||
- (void)categoryChangedViaSegmentsBar:(UISegmentedControl *)sender {
|
||||
// recalculate number of pages for new category and recreate emoji pages
|
||||
self.category = [self categoryNameAtIndex:sender.selectedSegmentIndex];
|
||||
[self setSelectedCategoryImageInSegmentControl:sender
|
||||
atIndex:sender.selectedSegmentIndex];
|
||||
self.pageControl.currentPage = 0;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)pageControlTouched:(UIPageControl *)sender {
|
||||
CGRect bounds = self.emojiPagesScrollView.bounds;
|
||||
bounds.origin.x = CGRectGetWidth(bounds) * sender.currentPage;
|
||||
bounds.origin.y = 0;
|
||||
// scrollViewDidScroll is called here. Page set at that time.
|
||||
[self.emojiPagesScrollView scrollRectToVisible:bounds animated:YES];
|
||||
}
|
||||
|
||||
// Track the contentOffset of the scroll view, and when it passes the mid
|
||||
// point of the current view’s width, the views are reconfigured.
|
||||
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
|
||||
CGFloat pageWidth = CGRectGetWidth(scrollView.frame);
|
||||
NSInteger newPageNumber = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
|
||||
if (self.pageControl.currentPage == newPageNumber) {
|
||||
return;
|
||||
}
|
||||
self.pageControl.currentPage = newPageNumber;
|
||||
[self setPage:self.pageControl.currentPage];
|
||||
}
|
||||
|
||||
#pragma mark change a page on scrollView
|
||||
|
||||
// Check if setting pageView for an index is required
|
||||
- (BOOL)requireToSetPageViewForIndex:(NSUInteger)index {
|
||||
if (index >= self.pageControl.numberOfPages) {
|
||||
return NO;
|
||||
}
|
||||
for (UMComEmojiPageView *page in self.pageViews) {
|
||||
if ((page.frame.origin.x / CGRectGetWidth(self.emojiPagesScrollView.bounds)) == index) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Create a pageView and add it to the scroll view.
|
||||
- (UMComEmojiPageView *)synthesizeEmojiPageView {
|
||||
CGRect pageViewFrame = CGRectMake(0,
|
||||
0,
|
||||
CGRectGetWidth(self.emojiPagesScrollView.bounds),
|
||||
CGRectGetHeight(self.emojiPagesScrollView.bounds));
|
||||
UMComEmojiPageView *pageView = [[UMComEmojiPageView alloc] initWithFrame: pageViewFrame
|
||||
backSpaceButtonImage:UMComImageWithImageName(@"um_emoji_delete")
|
||||
buttonSize:CGSizeMake(ButtonWidth, ButtonHeight)
|
||||
rows:3
|
||||
columns:7];
|
||||
pageView.delegate = self;
|
||||
[self.pageViews addObject:pageView];
|
||||
[self.emojiPagesScrollView addSubview:pageView];
|
||||
return pageView;
|
||||
}
|
||||
|
||||
// return a pageView that can be used in the current scrollView.
|
||||
// look for an available pageView in current pageView-s on scrollView.
|
||||
// If all are in use i.e. are of current page or neighbours
|
||||
// of current page, we create a new one
|
||||
|
||||
- (UMComEmojiPageView *)usableEmojiPageView {
|
||||
UMComEmojiPageView *pageView = nil;
|
||||
for (UMComEmojiPageView *page in self.pageViews) {
|
||||
NSUInteger pageNumber = page.frame.origin.x / CGRectGetWidth(self.emojiPagesScrollView.bounds);
|
||||
if (abs((int)(pageNumber - self.pageControl.currentPage)) > 1) {
|
||||
pageView = page;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pageView) {
|
||||
pageView = [self synthesizeEmojiPageView];
|
||||
}
|
||||
return pageView;
|
||||
}
|
||||
|
||||
// Set emoji page view for given index.
|
||||
- (void)setEmojiPageViewInScrollView:(UIScrollView *)scrollView atIndex:(NSUInteger)index {
|
||||
|
||||
if (![self requireToSetPageViewForIndex:index]) {
|
||||
return;
|
||||
}
|
||||
|
||||
UMComEmojiPageView *pageView = [self usableEmojiPageView];
|
||||
|
||||
// NSUInteger rows = [self numberOfRowsForFrameSize:scrollView.bounds.size];
|
||||
// NSUInteger columns = [self numberOfColumnsForFrameSize:scrollView.bounds.size];
|
||||
NSUInteger rows = RowNum;
|
||||
NSUInteger columns = ColumnNum;
|
||||
NSUInteger startingIndex = index * (rows * columns - 1);
|
||||
NSUInteger endingIndex = (index + 1) * (rows * columns - 1);
|
||||
NSMutableArray *buttonTexts = [self emojiTextsForCategory:self.category
|
||||
fromIndex:startingIndex
|
||||
toIndex:endingIndex];
|
||||
[pageView setButtonTexts:buttonTexts];
|
||||
pageView.frame = CGRectMake(index * CGRectGetWidth(scrollView.bounds),
|
||||
0,
|
||||
CGRectGetWidth(scrollView.bounds),
|
||||
CGRectGetHeight(scrollView.bounds));
|
||||
}
|
||||
|
||||
// Set the current page.
|
||||
// sets neightbouring pages too, as they are viewable by part scrolling.
|
||||
- (void)setPage:(NSInteger)page {
|
||||
[self setEmojiPageViewInScrollView:self.emojiPagesScrollView atIndex:page - 1];
|
||||
[self setEmojiPageViewInScrollView:self.emojiPagesScrollView atIndex:page];
|
||||
[self setEmojiPageViewInScrollView:self.emojiPagesScrollView atIndex:page + 1];
|
||||
}
|
||||
|
||||
- (void)purgePageViews {
|
||||
for (UMComEmojiPageView *page in self.pageViews) {
|
||||
page.delegate = nil;
|
||||
}
|
||||
self.pageViews = nil;
|
||||
}
|
||||
|
||||
#pragma mark data methods
|
||||
|
||||
- (NSUInteger)numberOfColumnsForFrameSize:(CGSize)frameSize {
|
||||
return (NSUInteger)floor(frameSize.width / ButtonWidth);
|
||||
}
|
||||
|
||||
- (NSUInteger)numberOfRowsForFrameSize:(CGSize)frameSize {
|
||||
return (NSUInteger)floor(frameSize.height / ButtonHeight);
|
||||
}
|
||||
|
||||
- (NSArray *)emojiListForCategory:(NSString *)category {
|
||||
return [self.emojis objectForKey:category];
|
||||
}
|
||||
|
||||
// for a given frame size of scroll view, return the number of pages
|
||||
// required to show all the emojis for a category
|
||||
- (NSUInteger)numberOfPagesForCategory:(NSString *)category inFrameSize:(CGSize)frameSize {
|
||||
|
||||
if ([category isEqualToString:segmentRecentName]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
NSUInteger emojiCount = [[self emojiListForCategory:category] count];
|
||||
NSUInteger numberOfRows = RowNum;
|
||||
NSUInteger numberOfColumns = ColumnNum;
|
||||
NSUInteger numberOfEmojisOnAPage = (numberOfRows * numberOfColumns) - 1;
|
||||
|
||||
NSUInteger numberOfPages = (NSUInteger)ceil((float)emojiCount / numberOfEmojisOnAPage);
|
||||
return numberOfPages;
|
||||
}
|
||||
|
||||
// return the emojis for a category, given a staring and an ending index
|
||||
- (NSMutableArray *)emojiTextsForCategory:(NSString *)category
|
||||
fromIndex:(NSUInteger)start
|
||||
toIndex:(NSUInteger)end {
|
||||
NSArray *emojis = [self emojiListForCategory:category];
|
||||
end = ([emojis count] > end)? end : [emojis count];
|
||||
NSIndexSet *index = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(start, end-start)];
|
||||
return [[emojis objectsAtIndexes:index] mutableCopy];
|
||||
}
|
||||
|
||||
#pragma mark EmojiPageViewDelegate
|
||||
// add the emoji to recents
|
||||
- (void)emojiPageView:(UMComEmojiPageView *)emojiPageView didUseEmoji:(NSString *)emoji {
|
||||
// [self setInRecentsEmoji:emoji];
|
||||
[self.delegate emojiKeyBoardView:self didUseEmoji:emoji];
|
||||
}
|
||||
|
||||
- (void)emojiPageViewDidPressBackSpace:(UMComEmojiPageView *)emojiPageView {
|
||||
[self.delegate emojiKeyBoardViewDidPressBackSpace:self];
|
||||
}
|
||||
|
||||
@end
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// AGEmojiPageView.h
|
||||
// AGEmojiKeyboard
|
||||
//
|
||||
// Created by Ayush on 09/05/13.
|
||||
// Copyright (c) 2013 Ayush. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@protocol AGEmojiPageViewDelegate;
|
||||
|
||||
@interface UMComEmojiPageView : UIView
|
||||
|
||||
@property (nonatomic, assign) id<AGEmojiPageViewDelegate> delegate;
|
||||
|
||||
/**
|
||||
Creates and returns an EmojiPageView
|
||||
|
||||
@param backSpaceButtonImage Imge to be used to present the back space button.
|
||||
@param buttonsSize Size for the button representing a single emoji
|
||||
@param rows Number of rows in a single EmojiPageView
|
||||
@param columns Number of columns in a single EmojiPageView. Also represents the number of emojis shown in a row.
|
||||
|
||||
@return An instance of EmojiPageView
|
||||
*/
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
backSpaceButtonImage:(UIImage *)backSpaceButtonImage
|
||||
buttonSize:(CGSize)buttonSize
|
||||
rows:(NSUInteger)rows
|
||||
columns:(NSUInteger)columns;
|
||||
|
||||
/**
|
||||
Sets texts on buttons in the EmojiPageView.
|
||||
|
||||
@param buttonTexts An array of texts to be set on buttons in EmojiPageView
|
||||
*/
|
||||
- (void)setButtonTexts:(NSMutableArray *)buttonTexts;
|
||||
|
||||
@end
|
||||
|
||||
@protocol AGEmojiPageViewDelegate <NSObject>
|
||||
|
||||
/**
|
||||
Delegate method called when user taps an emoji button
|
||||
@param emojiPageView EmojiPageView object on which user has tapped.
|
||||
@param emoji Emoji pressed by user
|
||||
*/
|
||||
- (void)emojiPageView:(UMComEmojiPageView *)emojiPageView didUseEmoji:(NSString *)emoji;
|
||||
|
||||
/**
|
||||
Delegate method called when user taps on the backspace button
|
||||
@param emojiPageView EmojiPageView object on which user has tapped.
|
||||
*/
|
||||
- (void)emojiPageViewDidPressBackSpace:(UMComEmojiPageView *)emojiPageView;
|
||||
|
||||
@end
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// AGEmojiPageView.m
|
||||
// AGEmojiKeyboard
|
||||
//
|
||||
// Created by Ayush on 09/05/13.
|
||||
// Copyright (c) 2013 Ayush. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UMComEmojiPageView.h"
|
||||
|
||||
#define BACKSPACE_BUTTON_TAG 10
|
||||
#define BUTTON_FONT_SIZE 32
|
||||
|
||||
@interface UMComEmojiPageView ()
|
||||
|
||||
@property (nonatomic) CGSize buttonSize;
|
||||
@property (nonatomic) NSMutableArray *buttons;
|
||||
@property (nonatomic) NSUInteger columns;
|
||||
@property (nonatomic) NSUInteger rows;
|
||||
@property (nonatomic) UIImage *backSpaceButtonImage;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UMComEmojiPageView
|
||||
|
||||
- (void)setButtonTexts:(NSMutableArray *)buttonTexts {
|
||||
|
||||
NSAssert(buttonTexts != nil, @"Array containing texts to be set on buttons is nil");
|
||||
|
||||
if (([self.buttons count] - 1) == [buttonTexts count]) {
|
||||
// just reset text on each button
|
||||
for (NSUInteger i = 0; i < [buttonTexts count]; ++i) {
|
||||
[self.buttons[i] setTitle:buttonTexts[i] forState:UIControlStateNormal];
|
||||
}
|
||||
} else {
|
||||
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
self.buttons = nil;
|
||||
self.buttons = [NSMutableArray arrayWithCapacity:self.rows * self.columns];
|
||||
for (NSUInteger i = 0; i < [buttonTexts count]; ++i) {
|
||||
if (i % (self.rows *self.columns -1) == 0 && i > 0) {
|
||||
continue;
|
||||
}
|
||||
UIButton *button = [self createButtonAtIndex:i];
|
||||
[button setTitle:buttonTexts[i] forState:UIControlStateNormal];
|
||||
[self addToViewButton:button];
|
||||
}
|
||||
UIButton *button = [self createButtonAtIndex:self.rows * self.columns - 1];
|
||||
[button setContentEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
|
||||
[button setImage:self.backSpaceButtonImage forState:UIControlStateNormal];
|
||||
button.tag = BACKSPACE_BUTTON_TAG;
|
||||
[self addToViewButton:button];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addToViewButton:(UIButton *)button {
|
||||
|
||||
NSAssert(button != nil, @"Button to be added is nil");
|
||||
|
||||
[self.buttons addObject:button];
|
||||
[self addSubview:button];
|
||||
}
|
||||
|
||||
// Padding is the expected space between two buttons.
|
||||
// Thus, space of top button = padding / 2
|
||||
// extra padding according to particular button's pos = pos * padding
|
||||
// Margin includes, size of buttons in between = pos * buttonSize
|
||||
// Thus, margin = padding / 2
|
||||
// + pos * padding
|
||||
// + pos * buttonSize
|
||||
|
||||
- (CGFloat)XMarginForButtonInColumn:(NSInteger)column {
|
||||
CGFloat padding = ((CGRectGetWidth(self.bounds) - self.columns * self.buttonSize.width) / self.columns);
|
||||
return (padding / 2 + column * (padding + self.buttonSize.width));
|
||||
}
|
||||
|
||||
- (CGFloat)YMarginForButtonInRow:(NSInteger)rowNumber {
|
||||
CGFloat padding = ((CGRectGetHeight(self.bounds) - self.rows * self.buttonSize.height) / self.rows);
|
||||
return (padding / 2 + rowNumber * (padding + self.buttonSize.height));
|
||||
}
|
||||
|
||||
- (UIButton *)createButtonAtIndex:(NSUInteger)index {
|
||||
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
button.titleLabel.font = [UIFont fontWithName:@"Apple color emoji" size:BUTTON_FONT_SIZE];
|
||||
NSInteger row = (NSInteger)(index / self.columns);
|
||||
NSInteger column = (NSInteger)(index % self.columns);
|
||||
button.frame = CGRectIntegral(CGRectMake([self XMarginForButtonInColumn:column],
|
||||
[self YMarginForButtonInRow:row],
|
||||
self.buttonSize.width,
|
||||
self.buttonSize.height));
|
||||
|
||||
[button addTarget:self
|
||||
action:@selector(emojiButtonPressed:)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
return button;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
backSpaceButtonImage:(UIImage *)backSpaceButtonImage
|
||||
buttonSize:(CGSize)buttonSize
|
||||
rows:(NSUInteger)rows
|
||||
columns:(NSUInteger)columns {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
_backSpaceButtonImage = backSpaceButtonImage;
|
||||
_buttonSize = buttonSize;
|
||||
_columns = columns;
|
||||
_rows = rows;
|
||||
_buttons = [[NSMutableArray alloc] initWithCapacity:rows * columns];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)emojiButtonPressed:(UIButton *)button {
|
||||
if (button.tag == BACKSPACE_BUTTON_TAG) {
|
||||
[self.delegate emojiPageViewDidPressBackSpace:self];
|
||||
return;
|
||||
}
|
||||
[self.delegate emojiPageView:self didUseEmoji:button.titleLabel.text];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user