From dbdc3e7ae0a93dbe4028d39189fc38b2b5f79702 Mon Sep 17 00:00:00 2001 From: liangj Date: Tue, 17 Oct 2017 17:03:35 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E8=8F=8A=E8=8A=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/ChatMessageCell/LCCKMessageSendStateView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKMessageSendStateView.m b/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKMessageSendStateView.m index 74ddb68c..d0c7f7c3 100644 --- a/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKMessageSendStateView.m +++ b/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKMessageSendStateView.m @@ -28,7 +28,7 @@ @implementation LCCKMessageSendStateView - (instancetype)init { if (self = [super init]) { - UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; indicatorView.hidden = YES; [self addSubview:self.indicatorView = indicatorView]; // KVO注册监听 From 85a35262fe4b1186fe7aff3523a525e75a424dc2 Mon Sep 17 00:00:00 2001 From: liangj Date: Mon, 23 Oct 2017 16:48:37 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E7=95=8C=E9=9D=A2=E4=BB=BF=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Conversation/View/ChatBar/LCCKChatBar.m | 31 ++- .../View/ChatBar/LCCKProgressHUD.h | 9 + .../View/ChatBar/LCCKProgressHUD.m | 227 ++++++++++++++---- .../ChatMessageCell/LCCKChatMessageCell.m | 8 +- .../LCCKChatVoiceMessageCell.m | 41 +++- .../Class/Tool/Vendor/VoiceLib/Mp3Recorder.h | 1 + .../Class/Tool/Vendor/VoiceLib/Mp3Recorder.m | 33 +++ 7 files changed, 296 insertions(+), 54 deletions(-) diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m index 57a4bb04..51958014 100644 --- a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m @@ -23,7 +23,7 @@ NSString *const kLCCKBatchDeleteTextPrefix = @"kLCCKBatchDeleteTextPrefix"; NSString *const kLCCKBatchDeleteTextSuffix = @"kLCCKBatchDeleteTextSuffix"; - +static CGFloat const kLCCKVolumeMaxTimeLength = 15; @interface LCCKChatBar () @property (strong, nonatomic) Mp3Recorder *MP3; @@ -57,6 +57,8 @@ @interface LCCKChatBar () = kLCCKVolumeMaxTimeLength) { + [self.MP3 stopRecord]; + } +} + #pragma mark - LCCKChatFaceViewDelegate - (void)faceViewSendFace:(NSString *)faceName { @@ -506,6 +516,7 @@ - (void)setup { - (void)startRecordVoice { [LCCKProgressHUD show]; self.voiceRecordButton.highlighted = YES; + self.volumeTimeLength = 0.0; [self.MP3 startRecord]; } @@ -513,7 +524,10 @@ - (void)startRecordVoice { * 取消录音 */ - (void)cancelRecordVoice { - [LCCKProgressHUD dismissWithMessage:@"取消录音"]; + if (self.volumeTimeLength >= kLCCKVolumeMaxTimeLength) { + return; + } + [LCCKProgressHUD dismissWithMessage:@""]; self.voiceRecordButton.highlighted = NO; [self.MP3 cancelRecord]; } @@ -522,6 +536,9 @@ - (void)cancelRecordVoice { * 录音结束 */ - (void)confirmRecordVoice { + if (self.volumeTimeLength >= kLCCKVolumeMaxTimeLength) { + return; + } [self.MP3 stopRecord]; } @@ -529,14 +546,20 @@ - (void)confirmRecordVoice { * 更新录音显示状态,手指向上滑动后提示松开取消录音 */ - (void)updateCancelRecordVoice { - [LCCKProgressHUD changeSubTitle:@"松开取消录音"]; + if (self.volumeTimeLength >= kLCCKVolumeMaxTimeLength) { + return; + } + [LCCKProgressHUD changeSubTitle:@"松开手指,取消发送"]; } /** * 更新录音状态,手指重新滑动到范围内,提示向上取消录音 */ - (void)updateContinueRecordVoice { - [LCCKProgressHUD changeSubTitle:@"向上滑动取消录音"]; + if (self.volumeTimeLength >= kLCCKVolumeMaxTimeLength) { + return; + } + [LCCKProgressHUD changeSubTitle:@"手指上滑,取消发送"]; } - (void)setShowType:(LCCKFunctionViewShowType)showType { diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKProgressHUD.h b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKProgressHUD.h index 51b92f95..98d11ec9 100644 --- a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKProgressHUD.h +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKProgressHUD.h @@ -16,6 +16,7 @@ typedef NS_ENUM(NSUInteger, LCCKProgressState){ LCCKProgressSuccess /**< 成功 */, LCCKProgressError /**< 出错,失败 */, LCCKProgressShort /**< 时间太短失败 */, + LCCKProgressOverTime /**< 超时 */, LCCKProgressMessage /**< 自定义失败提示 */, }; @@ -60,4 +61,12 @@ typedef NS_ENUM(NSUInteger, LCCKProgressState){ */ + (void)changeSubTitle:(NSString *)str; +/** + * 修改音量图片和时间倒计时Label + * + * @param volume 音量大小 + * @param timeLength 录音时长 + */ ++ (void)realtimeChangeVolumeImageView:(float)volume timeLength:(NSTimeInterval)timeLength; + @end diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKProgressHUD.m b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKProgressHUD.m index be1ba144..45b8f93a 100644 --- a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKProgressHUD.m +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKProgressHUD.m @@ -8,12 +8,12 @@ #import "LCCKProgressHUD.h" #import "UIImage+LCCKExtension.h" - +static CGFloat const kLCCKVolumeMaxTimeLength = 15; @interface LCCKProgressHUD () @property (assign, nonatomic) CGFloat angle; -@property (strong, nonatomic) NSTimer *timer; -@property (strong, nonatomic) UIImageView *edgeImageView; +//@property (strong, nonatomic) NSTimer *timer; +//@property (strong, nonatomic) UIImageView *edgeImageView; @property (strong, nonatomic) UILabel *centerLabel; @property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, strong) UILabel *subTitleLabel; @@ -22,6 +22,12 @@ @interface LCCKProgressHUD () @property (nonatomic, strong, readonly) UIWindow *overlayWindow; +@property (strong, nonatomic) UIView *bgView; +@property (strong, nonatomic) UIImageView *cancleImageView; +@property (strong, nonatomic) UIImageView *volumeImageView; +@property (strong, nonatomic) UIImageView *soundImageView; +@property (assign, nonatomic) CGFloat countdownTime; + @end @implementation LCCKProgressHUD @@ -35,10 +41,16 @@ - (instancetype)initWithFrame:(CGRect)frame { } - (void)setup{ - [self addSubview:self.edgeImageView]; - [self addSubview:self.centerLabel]; - [self addSubview:self.subTitleLabel]; - [self addSubview:self.titleLabel]; + + [self addSubview:self.bgView]; + + [self.bgView addSubview:self.cancleImageView]; + [self.bgView addSubview:self.volumeImageView]; + [self.bgView addSubview:self.soundImageView]; +// [self addSubview:self.edgeImageView]; + [self.bgView addSubview:self.centerLabel]; + [self.bgView addSubview:self.subTitleLabel]; + [self.bgView addSubview:self.titleLabel]; } #pragma mark - Private Methods @@ -46,10 +58,12 @@ - (void)setup{ - (void)show { self.angle = 0.0f; self.seconds = 0; - self.subTitleLabel.text = @"向上滑动取消"; - self.centerLabel.text = @"60"; + self.subTitleLabel.text = @"手指上滑,取消发送"; + self.subTitleLabel.backgroundColor = [UIColor clearColor]; +// self.centerLabel.text = @"15"; + self.countdownTime = kLCCKVolumeMaxTimeLength; self.titleLabel.text = @"录音时间"; - [self timer]; +// [self timer]; dispatch_async(dispatch_get_main_queue(), ^{ if(!self.superview) [[UIApplication sharedApplication].keyWindow addSubview:self]; @@ -58,35 +72,110 @@ - (void)show { } completion:nil]; [self setNeedsDisplay]; }); + + self.titleLabel.alpha = 0; + self.centerLabel.alpha = 0; + + _cancleImageView.alpha = 0; + _soundImageView.alpha = 1; + _volumeImageView.alpha = 1; } - (void)timerAction { self.angle -= 3; self.seconds ++ ; + + float second = self.countdownTime; + if (second <= 10.0f) { + _cancleImageView.alpha = 0; + _soundImageView.alpha = 0; + _volumeImageView.alpha = 0; + self.centerLabel.alpha = 1; + } + //超时做调整 +// if (second <= 0.1f) { +// [[LCCKProgressHUD sharedView]dismiss]; +// } + [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.09]; UIView.AnimationRepeatAutoreverses = YES; - self.edgeImageView.transform = CGAffineTransformMakeRotation(self.angle * (M_PI / 180.0f)); - float second = [self.centerLabel.text floatValue]; +// self.edgeImageView.transform = CGAffineTransformMakeRotation(self.angle * (M_PI / 180.0f)); if (second <= 10.0f) { self.centerLabel.textColor = [UIColor redColor]; } else { self.centerLabel.textColor = [UIColor yellowColor]; } - self.centerLabel.text = [NSString stringWithFormat:@"%.1f",second-0.1]; + self.countdownTime = second-0.1; + self.centerLabel.text = [NSString stringWithFormat:@"%.0f",self.countdownTime]; [UIView commitAnimations]; } - (void)setSubTitle:(NSString *)subTitle { self.subTitleLabel.text = subTitle; + if ([subTitle isEqualToString:@"松开手指,取消发送"]) { + self.subTitleLabel.backgroundColor = [[UIColor redColor]colorWithAlphaComponent:0.7]; + } else if ([subTitle isEqualToString:@"手指上滑,取消发送"]) { + self.subTitleLabel.backgroundColor = [UIColor clearColor]; + } + + if ((kLCCKVolumeMaxTimeLength - self.seconds/10.0) <= 10) { + return; + } + if ([subTitle isEqualToString:@"松开手指,取消发送"]) { + _cancleImageView.alpha = 1; + _soundImageView.alpha = 0; + _volumeImageView.alpha = 0; + } else if ([subTitle isEqualToString:@"手指上滑,取消发送"]) { + _cancleImageView.alpha = 0; + _soundImageView.alpha = 1; + _volumeImageView.alpha = 1; + } +} + +- (void)changeVolumeImageView:(float)volume timeLength:(NSTimeInterval)timeLength{ + NSString *imageName = @""; + if (volume <= -50) { + imageName = @"RecordingSignal001"; + } else if (volume <= -40) { + imageName = @"RecordingSignal002"; + } else if (volume <= -31) { + imageName = @"RecordingSignal003"; + } else if (volume <= -21) { + imageName = @"RecordingSignal004"; + } else if (volume <= -13) { + imageName = @"RecordingSignal005"; + } else if (volume <= -7) { + imageName = @"RecordingSignal006"; + } else if (volume <= -3) { + imageName = @"RecordingSignal007"; + } else { + imageName = @"RecordingSignal008"; + } + UIImage *image = [UIImage lcck_imageNamed:imageName bundleName:@"MessageBubble" bundleForClass:[self class]]; + self.volumeImageView.image = image; + + self.seconds = timeLength; + if ((kLCCKVolumeMaxTimeLength - self.seconds/10.0) <= 10) { + _cancleImageView.alpha = 0; + _soundImageView.alpha = 0; + _volumeImageView.alpha = 0; + self.centerLabel.alpha = 1; + self.centerLabel.textColor = [UIColor redColor]; + self.centerLabel.font = [UIFont systemFontOfSize:60]; + } else { + self.centerLabel.textColor = [UIColor yellowColor]; + } + self.centerLabel.text = [NSString stringWithFormat:@"%.0f",(kLCCKVolumeMaxTimeLength - self.seconds/10.0)]; } - (void)dismiss{ dispatch_async(dispatch_get_main_queue(), ^{ - [self.timer invalidate]; - self.timer = nil; +// [self.timer invalidate]; +// self.timer = nil; self.subTitleLabel.text = nil; self.titleLabel.text = nil; + self.centerLabel.font = [UIFont systemFontOfSize:20]; self.centerLabel.textColor = [UIColor whiteColor]; CGFloat timeLonger; @@ -136,55 +225,104 @@ - (void)setProgressState:(LCCKProgressState)progressState { case LCCKProgressMessage: break; } + self.centerLabel.font = [UIFont systemFontOfSize:20]; + self.centerLabel.textColor = [UIColor whiteColor]; } #pragma mark - Getters -- (NSTimer *)timer{ - if (_timer) { - [_timer invalidate]; - _timer = nil; +//- (NSTimer *)timer{ +// if (_timer) { +// [_timer invalidate]; +// _timer = nil; +// } +// _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 +// target:self +// selector:@selector(timerAction) +// userInfo:nil +// repeats:YES]; +// return _timer; +//} + +- (UIView *)bgView { + if (!_bgView) { + _bgView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 136, 136)]; + _bgView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7]; + _bgView.center = CGPointMake([[UIScreen mainScreen] bounds].size.width/2,[[UIScreen mainScreen] bounds].size.height/2); + _bgView.layer.cornerRadius = 5.0; + _bgView.layer.masksToBounds = YES; } - _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 - target:self - selector:@selector(timerAction) - userInfo:nil - repeats:YES]; - return _timer; + return _bgView; } - (UILabel *)centerLabel{ if (!_centerLabel) { - _centerLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 150, 40)]; + _centerLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 150, 60)]; _centerLabel.backgroundColor = [UIColor clearColor]; _centerLabel - .center = CGPointMake([[UIScreen mainScreen] bounds].size.width/2,[[UIScreen mainScreen] bounds].size.height/2); - _centerLabel.text = @"60"; + .center = CGPointMake([self.bgView bounds].size.width/2,[self.bgView bounds].size.height/2-10); + _centerLabel.text = [NSString stringWithFormat:@"%f",self.countdownTime]; _centerLabel.textAlignment = NSTextAlignmentCenter; - _centerLabel.font = [UIFont systemFontOfSize:30]; + _centerLabel.font = [UIFont systemFontOfSize:20]; _centerLabel.textColor = [UIColor yellowColor]; } return _centerLabel; } -- (UIImageView *)edgeImageView { - if (!_edgeImageView) { - _edgeImageView = [[UIImageView alloc]initWithImage:({ - NSString *imageName = @"chat_bar_record_circle"; - UIImage *image = [UIImage lcck_imageNamed:imageName bundleName:@"ChatKeyboard" bundleForClass:[self class]]; +//- (UIImageView *)edgeImageView { +// if (!_edgeImageView) { +// _edgeImageView = [[UIImageView alloc]initWithImage:({ +// NSString *imageName = @"chat_bar_record_circle"; +// UIImage *image = [UIImage lcck_imageNamed:imageName bundleName:@"ChatKeyboard" bundleForClass:[self class]]; +// image;}) +// ]; +// _edgeImageView.center = CGPointMake([[UIScreen mainScreen] bounds].size.width/2,[[UIScreen mainScreen] bounds].size.height/2); +// } +// return _edgeImageView; +//} +- (UIImageView *)cancleImageView { + if (!_cancleImageView) { + _cancleImageView = [[UIImageView alloc]initWithImage:({ + NSString *imageName = @"RecordCancel"; + UIImage *image = [UIImage lcck_imageNamed:imageName bundleName:@"MessageBubble" bundleForClass:[self class]]; image;}) ]; - _edgeImageView.center = CGPointMake([[UIScreen mainScreen] bounds].size.width/2,[[UIScreen mainScreen] bounds].size.height/2); + _cancleImageView.center = CGPointMake([self.bgView bounds].size.width/2,[self.bgView bounds].size.height/2-10); } - return _edgeImageView; + return _cancleImageView; } +- (UIImageView *)volumeImageView { + if (!_volumeImageView) { + _volumeImageView = [[UIImageView alloc]initWithImage:({ + NSString *imageName = @"RecordingSignal001"; + UIImage *image = [UIImage lcck_imageNamed:imageName bundleName:@"MessageBubble" bundleForClass:[self class]]; + image;}) + ]; + _volumeImageView.center = CGPointMake([self.bgView bounds].size.width/2+30,[self.bgView bounds].size.height/2-10); + } + return _volumeImageView; +} + +- (UIImageView *)soundImageView { + if (!_soundImageView) { + _soundImageView = [[UIImageView alloc]initWithImage:({ + NSString *imageName = @"RecordingBkg"; + UIImage *image = [UIImage lcck_imageNamed:imageName bundleName:@"MessageBubble" bundleForClass:[self class]]; + image;}) + ]; + _soundImageView.center = CGPointMake([self.bgView bounds].size.width/2-14,[self.bgView bounds].size.height/2-10); + } + return _soundImageView; +} + + - (UILabel *)titleLabel{ if (!_titleLabel) { _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 150, 20)]; - _titleLabel.center = CGPointMake([[UIScreen mainScreen] bounds].size.width/2,[[UIScreen mainScreen] bounds].size.height/2 - 30); + _titleLabel.center = CGPointMake([self.bgView bounds].size.width/2,[self.bgView bounds].size.height/2 - 30); _titleLabel.text = @"录音时间"; _titleLabel.textAlignment = NSTextAlignmentCenter; _titleLabel.font = [UIFont boldSystemFontOfSize:18]; @@ -196,12 +334,14 @@ - (UILabel *)titleLabel{ - (UILabel *)subTitleLabel{ if (!_subTitleLabel) { - _subTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 150, 20)]; - _subTitleLabel.center = CGPointMake([[UIScreen mainScreen] bounds].size.width/2,[[UIScreen mainScreen] bounds].size.height/2 + 30); - _subTitleLabel.text = @"向上滑动取消录音"; + _subTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 126, 20)]; + _subTitleLabel.center = CGPointMake([self.bgView bounds].size.width/2,[self.bgView bounds].size.height/2 + 48); + _subTitleLabel.text = @"手指上滑,取消发送"; _subTitleLabel.textAlignment = NSTextAlignmentCenter; _subTitleLabel.font = [UIFont boldSystemFontOfSize:14]; _subTitleLabel.textColor = [UIColor whiteColor]; + _subTitleLabel.layer.cornerRadius = 3.0; + _subTitleLabel.layer.masksToBounds = YES; } return _subTitleLabel; } @@ -223,7 +363,8 @@ + (LCCKProgressHUD *)sharedView { static LCCKProgressHUD *sharedView; dispatch_once(&once, ^ { sharedView = [[LCCKProgressHUD alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - sharedView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; +// sharedView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; + sharedView.backgroundColor = [UIColor clearColor]; }); return sharedView; } @@ -252,4 +393,8 @@ + (NSTimeInterval)seconds{ return [[LCCKProgressHUD sharedView] seconds] / 10; } ++ (void)realtimeChangeVolumeImageView:(float)volume timeLength:(NSTimeInterval)timeLength{ + [[LCCKProgressHUD sharedView] changeVolumeImageView:volume timeLength:timeLength]; +} + @end diff --git a/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKChatMessageCell.m b/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKChatMessageCell.m index f65577b5..a1ecf9d2 100644 --- a/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKChatMessageCell.m +++ b/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKChatMessageCell.m @@ -36,7 +36,7 @@ NSMutableDictionary const *LCCKChatMessageCellMediaTypeDict = nil; -static CGFloat const kAvatarImageViewWidth = 50.f; +static CGFloat const kAvatarImageViewWidth = 40.f; static CGFloat const kAvatarImageViewHeight = kAvatarImageViewWidth; static CGFloat const LCCKMessageSendStateViewWidthHeight = 30.f; static CGFloat const LCCKMessageSendStateViewLeftOrRightToMessageContentView = 2.f; @@ -425,7 +425,11 @@ - (LCCKContentView *)messageContentView { - (UIImageView *)messageReadStateImageView { if (!_messageReadStateImageView) { - _messageReadStateImageView = [[UIImageView alloc] init]; + _messageReadStateImageView = [[UIImageView alloc] initWithImage:({ + NSString *imageName = @"VoiceMessage_Unread"; + UIImage *image = [UIImage lcck_imageNamed:imageName bundleName:@"MessageBubble" bundleForClass:[self class]]; + image;}) + ]; } return _messageReadStateImageView; } diff --git a/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKChatVoiceMessageCell.m b/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKChatVoiceMessageCell.m index 250f1807..41e796b2 100644 --- a/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKChatVoiceMessageCell.m +++ b/ChatKit/Class/Module/Conversation/View/ChatMessageCell/LCCKChatVoiceMessageCell.m @@ -42,26 +42,36 @@ - (void)updateConstraints { make.right.equalTo(self.messageContentView.mas_right).with.offset(-12); make.centerY.equalTo(self.messageContentView.mas_centerY); }]; +// [self.messageVoiceSecondsLabel mas_makeConstraints:^(MASConstraintMaker *make) { +// make.right.equalTo(self.messageVoiceStatusImageView.mas_left).with.offset(-8); +// make.centerY.equalTo(self.messageContentView.mas_centerY); +// }]; [self.messageVoiceSecondsLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.right.equalTo(self.messageVoiceStatusImageView.mas_left).with.offset(-8); - make.centerY.equalTo(self.messageContentView.mas_centerY); + make.right.equalTo(self.messageContentView.mas_left).with.offset(-10); + make.bottom.equalTo(self.messageContentView.mas_bottom); }]; - self.messageVoiceSecondsLabel.textColor = self.conversationViewMessageRightTextColor; +// self.messageVoiceSecondsLabel.textColor = self.conversationViewMessageRightTextColor; + self.messageVoiceSecondsLabel.textColor = [UIColor lightGrayColor]; [self.messageIndicatorView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self.messageContentView); make.width.equalTo(@10); make.height.equalTo(@10); }]; } else if (self.messageOwner == LCCKMessageOwnerTypeOther) { - self.messageVoiceSecondsLabel.textColor = self.conversationViewMessageLeftTextColor; +// self.messageVoiceSecondsLabel.textColor = self.conversationViewMessageLeftTextColor; + self.messageVoiceSecondsLabel.textColor = [UIColor lightGrayColor]; [self.messageVoiceStatusImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.messageContentView.mas_left).with.offset(12); make.centerY.equalTo(self.messageContentView.mas_centerY); }]; +// [self.messageVoiceSecondsLabel mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.equalTo(self.messageVoiceStatusImageView.mas_right).with.offset(8); +// make.centerY.equalTo(self.messageContentView.mas_centerY); +// }]; [self.messageVoiceSecondsLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.messageVoiceStatusImageView.mas_right).with.offset(8); - make.centerY.equalTo(self.messageContentView.mas_centerY); + make.left.equalTo(self.messageContentView.mas_right).with.offset(10); + make.bottom.equalTo(self.messageContentView.mas_bottom); }]; [self.messageIndicatorView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self.messageContentView); @@ -79,7 +89,8 @@ - (void)updateConstraints { #pragma mark - Public Methods - (void)setup { - [self.messageContentView addSubview:self.messageVoiceSecondsLabel]; +// [self.messageContentView addSubview:self.messageVoiceSecondsLabel]; + [self addSubview:self.messageVoiceSecondsLabel]; [self.messageContentView addSubview:self.messageVoiceStatusImageView]; [self.messageContentView addSubview:self.messageIndicatorView]; UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapMessageImageViewGestureRecognizerHandler:)]; @@ -172,6 +183,22 @@ - (void)configureCellWithData:(LCCKMessage *)message { } } +- (void)setMessageSendState:(LCCKMessageSendState)messageSendState { + [super setMessageSendState:messageSendState]; + switch (self.messageSendState) { + case LCCKMessageSendStateSending: + self.messageVoiceSecondsLabel.hidden = YES; + break; + + case LCCKMessageSendStateFailed: + self.messageVoiceSecondsLabel.hidden = YES; + break; + default: + self.messageVoiceSecondsLabel.hidden = NO; + break; + } +} + #pragma mark - Getters - (UIImageView *)messageVoiceStatusImageView { diff --git a/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h b/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h index 172a38a0..bf1df782 100755 --- a/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h +++ b/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.h @@ -12,6 +12,7 @@ - (void)failRecord; - (void)beginConvert; - (void)endConvertWithMP3FileName:(NSString *)fileName; +- (void)realTimeVolumeSize:(float)size timeLength:(NSTimeInterval)timeLength; @end @interface Mp3Recorder : NSObject diff --git a/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.m b/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.m index fd0ba562..a57c67dc 100755 --- a/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.m +++ b/ChatKit/Class/Tool/Vendor/VoiceLib/Mp3Recorder.m @@ -18,6 +18,9 @@ @interface Mp3Recorder() @property (nonatomic, strong) AVAudioSession *session; @property (nonatomic, strong) AVAudioRecorder *recorder; +//开启timer实时把音量大小数据传出去 +@property (strong, nonatomic) NSTimer *timer; +@property (assign, nonatomic) NSTimeInterval seconds; @end @implementation Mp3Recorder @@ -75,11 +78,16 @@ - (void)startRecord [self setSesstion]; [self setRecorder]; [_recorder record]; + self.seconds = 0; + [self timer]; } - (void)stopRecord { + [self.timer invalidate]; + self.timer = nil; + double cTime = _recorder.currentTime; [_recorder stop]; @@ -97,6 +105,9 @@ - (void)stopRecord - (void)cancelRecord { + [self.timer invalidate]; + self.timer = nil; + [_recorder stop]; [_recorder deleteRecording]; } @@ -178,6 +189,28 @@ - (void)audio_PCMtoMP3 } +- (void)timerAction { + self.seconds++; + if (_delegate && [_delegate respondsToSelector:@selector(realTimeVolumeSize:timeLength:)]) { + [_recorder updateMeters]; + [_delegate realTimeVolumeSize:[_recorder averagePowerForChannel:1] timeLength:self.seconds]; + } +} + +#pragma mark - Getters +- (NSTimer *)timer{ + if (_timer) { + [_timer invalidate]; + _timer = nil; + } + _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 + target:self + selector:@selector(timerAction) + userInfo:nil + repeats:YES]; + return _timer; +} + #pragma mark - Path Utils - (NSString *)cafPath { NSString *cafPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tmp.caf"]; From 5d5264c3bdef2af6367904af0f6b7f523f4e8224 Mon Sep 17 00:00:00 2001 From: shuq Date: Wed, 25 Oct 2017 18:14:57 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E6=9B=B4=E6=8D=A2Emoji?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChatKit-OC/.DS_Store | Bin 0 -> 6148 bytes .../ChatKit-OC.xcodeproj/project.pbxproj | 48 +- .../Class/Module/Other/EmojisList.plist | 865 ++++++++++++++++++ .../Other/[\345\210\240\351\231\244]@2x.png" | Bin 0 -> 301 bytes ChatKit-OC/Podfile.lock | 10 +- ChatKit/Class/.DS_Store | Bin 0 -> 6148 bytes .../AGEmojiKeyboard/AGEmojiKeyBoardView.h | 143 +++ .../AGEmojiKeyboard/AGEmojiKeyBoardView.m | 429 +++++++++ .../ChatBar/AGEmojiKeyboard/AGEmojiPageView.h | 57 ++ .../ChatBar/AGEmojiKeyboard/AGEmojiPageView.m | 116 +++ .../Conversation/View/ChatBar/LCCKChatBar.m | 133 ++- 11 files changed, 1776 insertions(+), 25 deletions(-) create mode 100644 ChatKit-OC/.DS_Store create mode 100644 ChatKit-OC/Example/Class/Module/Other/EmojisList.plist create mode 100644 "ChatKit-OC/Example/Class/Module/Other/[\345\210\240\351\231\244]@2x.png" create mode 100644 ChatKit/Class/.DS_Store create mode 100644 ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiKeyBoardView.h create mode 100644 ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiKeyBoardView.m create mode 100644 ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiPageView.h create mode 100644 ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiPageView.m diff --git a/ChatKit-OC/.DS_Store b/ChatKit-OC/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7856042751fe7cac6b7f5863c41a3b6696b461f5 GIT binary patch literal 6148 zcmeHK!AiqG5Pe&FsPxi8o$RkJ40!S z9*Q8MGcfZulbPM@TiD3}2$NMg21Wn|RKeap%_k!7MLW_nPoEgl92dC5634j2X(!qp zzmWksyF;GV95+0<&GS3KGYUMR#slv0h=vgbZWpuhw5Y2_H}i6}YkpPddAV8^!27}L zd75RX^{cx4R(>B7>o#TW7!-a0b>4$o&whf|+5fn63_* z)B+IYH!=yw(o0BAG|UWJMZTc~O(kk-uofd|I{ne&GQ(C;(-Exs2)1&t4ke`3Ie$#y z2$`Z=XTTZQW?)YrM^gXKzV83Gll;jUa0dPq1EHT!^9i?PwY9T3skM=MO%;*2R&kxe iK`O /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 5852033203B0746EE8645654 /* 📦 Copy Pods Resources */ = { @@ -890,9 +901,34 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-ChatKit-OC/Pods-ChatKit-OC-resources.sh", + "${PODS_ROOT}/AVOSCloud/AVOS/AVOSCloud/AVOSCloud_Art.inc", + "${PODS_ROOT}/../../ChatKit/Class/Resources/BarButtonIcon.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/ChatKeyboard.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/DateTools.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/Emoji.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/LCCKPBLocalizations.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/LCCKPhotoBrowser.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/MBProgressHUD.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/MessageBubble.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/Other.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/Placeholder.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Resources/VoiceMessageSource.bundle", + "${PODS_ROOT}/../../ChatKit/Class/Module/ContactList/View/LCCKContactCell.xib", + "${PODS_ROOT}/MJRefresh/MJRefresh/MJRefresh.bundle", + $PODS_CONFIGURATION_BUILD_DIR/MWPhotoBrowser/MWPhotoBrowser.bundle, + "${PODS_ROOT}/RedPacketAlipay/AlipaySDK.bundle", + "${PODS_ROOT}/RedpacketLib/RedpacketStaticLib/resources/RedPacketResource.bundle", + "${PODS_ROOT}/TWMessageBarManager/Classes/Icons/icon-error.png", + "${PODS_ROOT}/TWMessageBarManager/Classes/Icons/icon-error@2x.png", + "${PODS_ROOT}/TWMessageBarManager/Classes/Icons/icon-info.png", + "${PODS_ROOT}/TWMessageBarManager/Classes/Icons/icon-info@2x.png", + "${PODS_ROOT}/TWMessageBarManager/Classes/Icons/icon-success.png", + "${PODS_ROOT}/TWMessageBarManager/Classes/Icons/icon-success@2x.png", ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1108,7 +1144,7 @@ CODE_SIGN_ENTITLEMENTS = "ChatKit-OC.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = Y6X8P44TM5; + DEVELOPMENT_TEAM = 44PUDQ6NP3; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Example/Class/Module/Other/Info.plist"; @@ -1138,7 +1174,7 @@ "\"$(SRCROOT)/../../RedpacketStaticLib/AlipayLib\"/**", ); OTHER_LDFLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = com.chatkit.leancloud; + PRODUCT_BUNDLE_IDENTIFIER = com.leleyun.medassn; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1155,7 +1191,7 @@ CODE_SIGN_ENTITLEMENTS = "ChatKit-OC.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = Y6X8P44TM5; + DEVELOPMENT_TEAM = 44PUDQ6NP3; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Example/Class/Module/Other/Info.plist"; @@ -1185,7 +1221,7 @@ "\"$(SRCROOT)/../../RedpacketStaticLib/AlipayLib\"/**", ); OTHER_LDFLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = com.chatkit.leancloud; + PRODUCT_BUNDLE_IDENTIFIER = com.leleyun.medassn; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/ChatKit-OC/Example/Class/Module/Other/EmojisList.plist b/ChatKit-OC/Example/Class/Module/Other/EmojisList.plist new file mode 100644 index 00000000..69df5a4b --- /dev/null +++ b/ChatKit-OC/Example/Class/Module/Other/EmojisList.plist @@ -0,0 +1,865 @@ + + + + + Nature + + 🐶 + 🐺 + 🐱 + 🐭 + 🐹 + 🐰 + 🐸 + 🐯 + 🐨 + 🐻 + 🐷 + 🐽 + 🐮 + 🐗 + 🐵 + 🐒 + 🐴 + 🐑 + 🐘 + 🐼 + 🐧 + 🐦 + 🐤 + 🐥 + 🐣 + 🐔 + 🐍 + 🐢 + 🐛 + 🐝 + 🐜 + 🐞 + 🐌 + 🐙 + 🐚 + 🐠 + 🐟 + 🐬 + 🐳 + 🐋 + 🐄 + 🐏 + 🐀 + 🐃 + 🐅 + 🐇 + 🐉 + 🐎 + 🐐 + 🐓 + 🐕 + 🐖 + 🐁 + 🐂 + 🐲 + 🐡 + 🐊 + 🐫 + 🐪 + 🐆 + 🐈 + 🐩 + 🐾 + 💐 + 🌸 + 🌷 + 🍀 + 🌹 + 🌻 + 🌺 + 🍁 + 🍃 + 🍂 + 🌿 + 🌾 + 🍄 + 🌵 + 🌴 + 🌲 + 🌳 + 🌰 + 🌱 + 🌼 + 🌐 + 🌞 + 🌝 + 🌚 + 🌑 + 🌒 + 🌓 + 🌔 + 🌕 + 🌖 + 🌗 + 🌘 + 🌜 + 🌛 + 🌙 + 🌍 + 🌎 + 🌏 + 🌋 + 🌌 + 🌠 + + + + + + + + + 🌀 + 🌁 + 🌈 + 🌊 + + Objects + + 🎍 + 💝 + 🎎 + 🎒 + 🎓 + 🎏 + 🎆 + 🎇 + 🎐 + 🎑 + 🎃 + 👻 + 🎅 + 🎄 + 🎁 + 🎋 + 🎉 + 🎊 + 🎈 + 🎌 + 🔮 + 🎥 + 📷 + 📹 + 📼 + 💿 + 📀 + 💽 + 💾 + 💻 + 📱 + + 📞 + 📟 + 📠 + 📡 + 📺 + 📻 + 🔊 + 🔉 + 🔈 + 🔇 + 🔔 + 🔕 + 📢 + 📣 + + + + + 🔓 + 🔒 + 🔏 + 🔐 + 🔑 + 🔎 + 💡 + 🔦 + 🔆 + 🔅 + 🔌 + 🔋 + 🔍 + 🛁 + 🛀 + 🚿 + 🚽 + 🔧 + 🔩 + 🔨 + 🚪 + 🚬 + 💣 + 🔫 + 🔪 + 💊 + 💉 + 💰 + 💴 + 💵 + 💷 + 💶 + 💳 + 💸 + 📲 + 📧 + 📥 + 📤 + + 📩 + 📨 + 📯 + 📫 + 📪 + 📬 + 📭 + 📮 + 📦 + 📝 + 📄 + 📃 + 📑 + 📊 + 📈 + 📉 + 📜 + 📋 + 📅 + 📆 + 📇 + 📁 + 📂 + + 📌 + 📎 + + + 📏 + 📐 + 📕 + 📗 + 📘 + 📙 + 📓 + 📔 + 📒 + 📚 + 📖 + 🔖 + 📛 + 🔬 + 🔭 + 📰 + 🎨 + 🎬 + 🎤 + 🎧 + 🎼 + 🎵 + 🎶 + 🎹 + 🎻 + 🎺 + 🎷 + 🎸 + 👾 + 🎮 + 🃏 + 🎴 + 🀄 + 🎲 + 🎯 + 🏈 + 🏀 + + + 🎾 + 🎱 + 🏉 + 🎳 + + 🚵 + 🚴 + 🏁 + 🏇 + 🏆 + 🎿 + 🏂 + 🏊 + 🏄 + 🎣 + + 🍵 + 🍶 + 🍼 + 🍺 + 🍻 + 🍸 + 🍹 + 🍷 + 🍴 + 🍕 + 🍔 + 🍟 + 🍗 + 🍖 + 🍝 + 🍛 + 🍤 + 🍱 + 🍣 + 🍥 + 🍙 + 🍘 + 🍚 + 🍜 + 🍲 + 🍢 + 🍡 + 🍳 + 🍞 + 🍩 + 🍮 + 🍦 + 🍨 + 🍧 + 🎂 + 🍰 + 🍪 + 🍫 + 🍬 + 🍭 + 🍯 + 🍎 + 🍏 + 🍊 + 🍋 + 🍒 + 🍇 + 🍉 + 🍓 + 🍑 + 🍈 + 🍌 + 🍐 + 🍍 + 🍠 + 🍆 + 🍅 + 🌽 + + People + + 😄 + 😃 + 😀 + 😊 + + 😉 + 😍 + 😘 + 😚 + 😗 + 😙 + 😜 + 😝 + 😛 + 😳 + 😁 + 😔 + 😌 + 😒 + 😞 + 😣 + 😢 + 😂 + 😭 + 😪 + 😥 + 😰 + 😅 + 😓 + 😩 + 😫 + 😨 + 😱 + 😠 + 😡 + 😤 + 😖 + 😆 + 😋 + 😷 + 😎 + 😴 + 😵 + 😲 + 😟 + 😦 + 😧 + 😈 + 👿 + 😮 + 😬 + 😐 + 😕 + 😯 + 😶 + 😇 + 😏 + 😑 + 👲 + 👳 + 👮 + 👷 + 💂 + 👶 + 👦 + 👧 + 👨 + 👩 + 👴 + 👵 + 👱 + 👼 + 👸 + 😺 + 😸 + 😻 + 😽 + 😼 + 🙀 + 😿 + 😹 + 😾 + 👹 + 👺 + 🙈 + 🙉 + 🙊 + 💀 + 👽 + 💩 + 🔥 + + 🌟 + 💫 + 💥 + 💢 + 💦 + 💧 + 💤 + 💨 + 👂 + 👀 + 👃 + 👅 + 👄 + 👍 + 👎 + 👌 + 👊 + + + 👋 + + 👐 + 👆 + 👇 + 👉 + 👈 + 🙌 + 🙏 + + 👏 + 💪 + 🚶 + 🏃 + 💃 + 👫 + 👪 + 👬 + 👭 + 💏 + 💑 + 👯 + 🙆 + 🙅 + 💁 + 🙋 + 💆 + 💇 + 💅 + 👰 + 🙎 + 🙍 + 🙇 + 🎩 + 👑 + 👒 + 👟 + 👞 + 👡 + 👠 + 👢 + 👕 + 👔 + 👚 + 👗 + 🎽 + 👖 + 👘 + 👙 + 💼 + 👜 + 👝 + 👛 + 👓 + 🎀 + 🌂 + 💄 + 💛 + 💙 + 💜 + 💚 + + 💔 + 💗 + 💓 + 💕 + 💖 + 💞 + 💘 + 💌 + 💋 + 💍 + 💎 + 👤 + 👥 + 💬 + 👣 + 💭 + + Places + + 🏠 + 🏡 + 🏫 + 🏢 + 🏣 + 🏥 + 🏦 + 🏪 + 🏩 + 🏨 + 💒 + + 🏬 + 🏤 + 🌇 + 🌆 + 🏯 + 🏰 + + 🏭 + 🗼 + 🗾 + 🗻 + 🌄 + 🌅 + 🌃 + 🗽 + 🌉 + 🎠 + 🎡 + + 🎢 + 🚢 + + 🚤 + 🚣 + + 🚀 + + 💺 + 🚁 + 🚂 + 🚊 + 🚉 + 🚞 + 🚆 + 🚄 + 🚅 + 🚈 + 🚇 + 🚝 + 🚋 + 🚃 + 🚎 + 🚌 + 🚍 + 🚙 + 🚘 + 🚗 + 🚕 + 🚖 + 🚛 + 🚚 + 🚨 + 🚓 + 🚔 + 🚒 + 🚑 + 🚐 + 🚲 + 🚡 + 🚟 + 🚠 + 🚜 + 💈 + 🚏 + 🎫 + 🚦 + 🚥 + + 🚧 + 🔰 + + 🏮 + 🎰 + + 🗿 + 🎪 + 🎭 + 📍 + 🚩 + 🇯🇵 + 🇰🇷 + 🇩🇪 + 🇨🇳 + 🇺🇸 + 🇫🇷 + 🇪🇸 + 🇮🇹 + 🇷🇺 + + Symbols + + 1⃣ + 2⃣ + 3⃣ + 4⃣ + 5⃣ + 6⃣ + 7⃣ + 8⃣ + 9⃣ + 0⃣ + 🔟 + 🔢 + #⃣ + 🔣 + + + + + 🔠 + 🔡 + 🔤 + + + + + + + 🔄 + + + 🔼 + 🔽 + + + + + + + + + + 🆗 + 🔀 + 🔁 + 🔂 + 🆕 + 🆙 + 🆒 + 🆓 + 🆖 + 📶 + 🎦 + 🈁 + 🈯 + 🈳 + 🈵 + 🈴 + 🈲 + 🉐 + 🈹 + 🈺 + 🈶 + 🈚 + 🚻 + 🚹 + 🚺 + 🚼 + 🚾 + 🚰 + 🚮 + 🅿 + + 🚭 + 🈷 + 🈸 + 🈂 + + 🛂 + 🛄 + 🛅 + 🛃 + 🉑 + + + 🆑 + 🆘 + 🆔 + 🚫 + 🔞 + 📵 + 🚯 + 🚱 + 🚳 + 🚷 + 🚸 + + + + + + + 💟 + 🆚 + 📳 + 📴 + 🅰 + 🅱 + 🆎 + 🅾 + 💠 + + + + + + + + + + + + + + + + 🔯 + 🏧 + 💹 + 💲 + 💱 + © + ® + + + + + + + + + + 🔝 + 🔚 + 🔙 + 🔛 + 🔜 + 🔃 + 🕛 + 🕧 + 🕐 + 🕜 + 🕑 + 🕝 + 🕒 + 🕞 + 🕓 + 🕟 + 🕔 + 🕠 + 🕕 + 🕖 + 🕗 + 🕘 + 🕙 + 🕚 + 🕡 + 🕢 + 🕣 + 🕤 + 🕥 + 🕦 + + + + + + + + + 💮 + 💯 + + + 🔘 + 🔗 + + + + 🔱 + + + + + + + 🔺 + 🔲 + 🔳 + + + 🔴 + 🔵 + 🔻 + + + 🔶 + 🔷 + 🔸 + 🔹 + + + diff --git "a/ChatKit-OC/Example/Class/Module/Other/[\345\210\240\351\231\244]@2x.png" "b/ChatKit-OC/Example/Class/Module/Other/[\345\210\240\351\231\244]@2x.png" new file mode 100644 index 0000000000000000000000000000000000000000..113e20f01e42a726b96d6a196232db68d7497fe7 GIT binary patch literal 301 zcmV+|0n+}7P)j!c74JU$v~UdX`)CVv z^_brF*cp9j3pI9c?A&IRfxFXPV=Y({t4}_p!k8(ON9$TIu=@)nV3kdTy%Xz=R(Jfu zu+GLxr3TGdN-7*I_iF|X--6~^>enEaQv^w-qMgDi#nP^nZZmCAN5fDS=+P#~qN00000NkvXXu0mjfnW%-2 literal 0 HcmV?d00001 diff --git a/ChatKit-OC/Podfile.lock b/ChatKit-OC/Podfile.lock index ba78cd17..eeea7a9b 100644 --- a/ChatKit-OC/Podfile.lock +++ b/ChatKit-OC/Podfile.lock @@ -9,7 +9,7 @@ PODS: - AVOSCloudIM/_NOARC (= 7.2.0) - AVOSCloudIM/_NOARC (7.2.0): - AVOSCloud (= 7.2.0) - - ChatKit (0.10.1): + - ChatKit (1.0.0): - AVOSCloud (~> 7.2.0) - AVOSCloudIM (~> 7.2.0) - CYLDeallocBlockExecutor (~> 1.1.2) @@ -64,12 +64,12 @@ DEPENDENCIES: EXTERNAL SOURCES: ChatKit: - :path: "../" + :path: ../ SPEC CHECKSUMS: AVOSCloud: 9f09a2a734fe980685866feded7f6129141e9336 AVOSCloudIM: a14d3ccf0808dff33160a3287c84aa7e3fa17995 - ChatKit: 32a8466185293a46aa76a562248216bcc20f7168 + ChatKit: b9c6a7a60848bbe16f4983188a2bec17570e0981 CYLDeallocBlockExecutor: ecf39e45dcead9e120f460df5668b8f5093d178e CYLTabBarController: 8d99fccf22866fe18c978c5ff863dc6051da45ff CYLTableViewRowAction: 66bd3f7478b46894ff40b74d892fc85aed41656b @@ -87,10 +87,10 @@ SPEC CHECKSUMS: pop: 82ca6b068ce9278fd350fd9dd09482a0ce9492e6 RedPacketAlipay: a5de6db2e2671fc9255d6d396be869e3ba2f0489 RedpacketLib: e15853d93ac35141a1247b6ad79d6acb731d8704 - SDWebImage: '098e97e6176540799c27e804c96653ee0833d13c' + SDWebImage: 098e97e6176540799c27e804c96653ee0833d13c TWMessageBarManager: fd84e7948ba7968a2b5d9454859135761214ec56 UITableView+FDTemplateLayoutCell: 5c949b4a5059c404b442926c0e80f81d10a2d66f PODFILE CHECKSUM: 7d90ea9ead990467a4361ec54f56c20830ebe416 -COCOAPODS: 1.2.1 +COCOAPODS: 1.3.1 diff --git a/ChatKit/Class/.DS_Store b/ChatKit/Class/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a68fddd25f115d79b7d9539a3ef50a9f7aea5903 GIT binary patch literal 6148 zcmeHKJ8DBg3>+mc9MZUSxmU;y7UNtXzCa*0Zh{RCPW>vMD@V)dLx_2H6G&r5AkD5; zvyV5$(-Qz&9M@0448WA`h?9r0`MLYZ?kZzMI`25*fH!RL@wpmRUrspp0WZ$M{x|=y zd*AQ2dGlqevQj__NC7Dz1*E_q6!6|ln?5EgN&zV#1%4Fp??a4Ifrdwwh2Zp3eJQl*4+Wq7;w< z=L+2CcIN&6nSN#dKPPD?1*E`DDPWW3YPsMmRc{@=ocG#Bf2DiP7u}8PpfE%`CPq8v g#@q2cin6Zxn&-W6NDMmjK_}{Gz;%&Hf&W(E8+<(#mjD0& literal 0 HcmV?d00001 diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiKeyBoardView.h b/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiKeyBoardView.h new file mode 100644 index 00000000..7c0f0669 --- /dev/null +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiKeyBoardView.h @@ -0,0 +1,143 @@ +// +// 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 + +typedef NS_ENUM(NSInteger, AGEmojiKeyboardViewCategoryImage) { + AGEmojiKeyboardViewCategoryImageRecent, + AGEmojiKeyboardViewCategoryImageFace, + AGEmojiKeyboardViewCategoryImageBell, + AGEmojiKeyboardViewCategoryImageFlower, + AGEmojiKeyboardViewCategoryImageCar, + AGEmojiKeyboardViewCategoryImageCharacters +}; + +@protocol AGEmojiKeyboardViewDelegate; +@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 AGEmojiKeyboardView : 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 delegate; +@property (nonatomic, weak) id 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)dataSource; + +@end + + +/** + Protocol to be followed by the dataSource of `AGEmojiKeyboardView`. + */ +@protocol AGEmojiKeyboardViewDataSource + +/** + 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:(AGEmojiKeyboardView *)emojiKeyboardView + imageForSelectedCategory:(AGEmojiKeyboardViewCategoryImage)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:(AGEmojiKeyboardView *)emojiKeyboardView + imageForNonSelectedCategory:(AGEmojiKeyboardViewCategoryImage)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:(AGEmojiKeyboardView *)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. + */ +- (AGEmojiKeyboardViewCategoryImage)defaultCategoryForEmojiKeyboardView:(AGEmojiKeyboardView *)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:(AGEmojiKeyboardView *)emojiKeyboardView; + +@end + + +/** + Protocol to be followed by the delegate of `AGEmojiKeyboardView`. + */ +@protocol AGEmojiKeyboardViewDelegate + +/** + 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:(AGEmojiKeyboardView *)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:(AGEmojiKeyboardView *)emojiKeyBoardView; + +@end diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiKeyBoardView.m b/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiKeyBoardView.m new file mode 100644 index 00000000..1bcdcf4a --- /dev/null +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiKeyBoardView.m @@ -0,0 +1,429 @@ +// +// AGEmojiKeyboardView.m +// AGEmojiKeyboard +// +// Created by Ayush on 09/05/13. +// Copyright (c) 2013 Ayush. All rights reserved. +// + +#import "AGEmojiKeyBoardView.h" +#import "AGEmojiPageView.h" + +#define SCREENWIDTH [[UIScreen mainScreen] bounds].size.width + +#define kLCCKTopLineBackgroundColor [UIColor colorWithRed:184/255.0f green:184/255.0f blue:184/255.0f alpha:1.0f] + +static const CGFloat ButtonWidth = 45; +static const CGFloat ButtonHeight = 37; + +static const NSUInteger DefaultRecentEmojisMaintainedCount = 50; + +static NSString *const segmentRecentName = @"Recent"; +NSString *const RecentUsedEmojiCharactersKey = @"RecentUsedEmojiCharactersKey"; + + +@interface AGEmojiKeyboardView () + +@property (nonatomic) UISegmentedControl *segmentsBar; +@property (nonatomic) UIPageControl *pageControl; +@property (nonatomic) UIScrollView *emojiPagesScrollView; +@property (nonatomic) UIView *bottomView; +@property (nonatomic) NSDictionary *emojis; +@property (nonatomic) NSMutableArray *pageViews; +@property (nonatomic) NSString *category; +@property (weak, nonatomic) UIButton *sendButton; + +@end + +@implementation AGEmojiKeyboardView + +- (NSDictionary *)emojis { + if (!_emojis) { + NSBundle *selfBundle = [NSBundle bundleForClass:[self class]]; + NSString *plistPath = [selfBundle pathForResource:@"EmojisList" + ofType:@"plist"]; + _emojis = [[NSDictionary dictionaryWithContentsOfFile:plistPath] copy]; + } + return _emojis; +} + +- (NSString *)categoryNameAtIndex:(NSUInteger)index { + NSArray *categoryList = @[segmentRecentName, @"People", @"Objects", @"Nature", @"Places", @"Symbols"]; + return categoryList[index]; +} + +- (AGEmojiKeyboardViewCategoryImage)defaultSelectedCategory { + if ([self.dataSource respondsToSelector:@selector(defaultCategoryForEmojiKeyboardView:)]) { + return [self.dataSource defaultCategoryForEmojiKeyboardView:self]; + } + return AGEmojiKeyboardViewCategoryImageRecent; +} + +- (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 (AGEmojiKeyboardViewCategoryImage i = AGEmojiKeyboardViewCategoryImageRecent; + 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 (AGEmojiKeyboardViewCategoryImage i = AGEmojiKeyboardViewCategoryImageRecent; + i <= AGEmojiKeyboardViewCategoryImageCharacters; + ++i) { + [array addObject:[self.dataSource emojiKeyboardView:self imageForNonSelectedCategory:i]]; + } + }); + return array; +} + +// recent emojis are backed in NSUserDefaults to save them across app restarts. +- (NSMutableArray *)recentEmojis { + NSArray *emojis = [[NSUserDefaults standardUserDefaults] arrayForKey:RecentUsedEmojiCharactersKey]; + NSMutableArray *recentEmojis = [emojis mutableCopy]; + if (recentEmojis == nil) { + recentEmojis = [NSMutableArray array]; + } + return recentEmojis; +} + +- (void)setRecentEmojis:(NSMutableArray *)recentEmojis { + // remove emojis if they cross the cache maintained limit + if ([recentEmojis count] > self.recentEmojisMaintainedCount) { + NSRange indexRange = NSMakeRange(self.recentEmojisMaintainedCount, + [recentEmojis count] - self.recentEmojisMaintainedCount); + NSIndexSet *indexesToBeRemoved = [NSIndexSet indexSetWithIndexesInRange:indexRange]; + [recentEmojis removeObjectsAtIndexes:indexesToBeRemoved]; + } + [[NSUserDefaults standardUserDefaults] setObject:recentEmojis forKey:RecentUsedEmojiCharactersKey]; +} + +- (instancetype)initWithFrame:(CGRect)frame dataSource:(id)dataSource { + self = [super initWithFrame:frame]; + if (self) { + // initialize category + + _dataSource = dataSource; + + self.category = [self categoryNameAtIndex:self.defaultSelectedCategory]; + + CGRect scrollViewFrame = CGRectMake(0,0, + CGRectGetWidth(self.bounds), + CGRectGetHeight(self.bounds) - 40 - 35); + 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]; + + 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),15); + 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.emojiPagesScrollView.bounds), + pageControlSize.width, + pageControlSize.height); + self.pageControl.frame = CGRectIntegral(pageControlFrame); + [self.pageControl addTarget:self + action:@selector(pageControlTouched:) + forControlEvents:UIControlEventValueChanged]; + [self addSubview:self.pageControl]; + + self.segmentsBar = [[UISegmentedControl alloc] initWithItems:self.imagesForSelectedSegments]; + self.segmentsBar.frame = CGRectMake(0, + CGRectGetHeight(self.bounds) - 50, + CGRectGetWidth(self.bounds), + 45); + self.segmentsBar.autoresizingMask = UIViewAutoresizingFlexibleWidth; + [self.segmentsBar addTarget:self + action:@selector(categoryChangedViaSegmentsBar:) + forControlEvents:UIControlEventValueChanged]; + [self setSelectedCategoryImageInSegmentControl:self.segmentsBar + atIndex:self.defaultSelectedCategory]; + self.segmentsBar.selectedSegmentIndex = self.defaultSelectedCategory; + [self addSubview:self.segmentsBar]; + + self.bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.bounds) - 40, SCREENWIDTH, 40)]; + self.bottomView.autoresizingMask = UIViewAutoresizingFlexibleWidth; + UIImageView *topLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, SCREENWIDTH - 70, 1.0f)]; + topLine.backgroundColor = kLCCKTopLineBackgroundColor; + [self.bottomView addSubview:topLine]; + UIButton *sendButton = [[UIButton alloc] initWithFrame:CGRectMake(SCREENWIDTH - 70, 0, 70, 40)]; + sendButton.backgroundColor = [UIColor colorWithRed:0.0f/255.0f green:70.0f/255.0f blue:1.0f alpha:1.0f]; + [sendButton setTitle:@"发送" forState:UIControlStateNormal]; + [sendButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [sendButton addTarget:self action:@selector(sendAction:) forControlEvents:UIControlEventTouchUpInside]; + [self.bottomView addSubview:self.sendButton = sendButton]; + [self addSubview:self.bottomView]; + + self.segmentsBar.hidden = YES; + self.category = [self categoryNameAtIndex:1]; + self.pageControl.currentPage = 0; + [self setNeedsLayout]; + } + 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.emojiPagesScrollView.bounds), + pageControlSize.width, + pageControlSize.height); + self.pageControl.frame = CGRectIntegral(pageControlFrame); + + self.emojiPagesScrollView.frame = CGRectMake(0, + 0, + CGRectGetWidth(self.bounds), + CGRectGetHeight(self.bounds) - 75); + [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 (AGEmojiPageView *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. +- (AGEmojiPageView *)synthesizeEmojiPageView { + NSUInteger rows = [self numberOfRowsForFrameSize:self.emojiPagesScrollView.bounds.size]; + NSUInteger columns = [self numberOfColumnsForFrameSize:self.emojiPagesScrollView.bounds.size]; + CGRect pageViewFrame = CGRectMake(0, + 0, + CGRectGetWidth(self.emojiPagesScrollView.bounds), + CGRectGetHeight(self.emojiPagesScrollView.bounds)); + AGEmojiPageView *pageView = [[AGEmojiPageView alloc] initWithFrame: pageViewFrame + backSpaceButtonImage:[self.dataSource backSpaceButtonImageForEmojiKeyboardView:self] + buttonSize:CGSizeMake(ButtonWidth, ButtonHeight) + rows:rows + columns:columns]; + 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 + +- (AGEmojiPageView *)usableEmojiPageView { + AGEmojiPageView *pageView = nil; + for (AGEmojiPageView *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; + } + + AGEmojiPageView *pageView = [self usableEmojiPageView]; + + NSUInteger rows = [self numberOfRowsForFrameSize:scrollView.bounds.size]; + NSUInteger columns = [self numberOfColumnsForFrameSize:scrollView.bounds.size]; + 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 (AGEmojiPageView *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 { + if ([category isEqualToString:segmentRecentName]) { + return [self recentEmojis]; + } + 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 = [self numberOfRowsForFrameSize:frameSize]; + NSUInteger numberOfColumns = [self numberOfColumnsForFrameSize:frameSize]; + 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 + +- (void)setInRecentsEmoji:(NSString *)emoji { + NSAssert(emoji != nil, @"Emoji can't be nil"); + + NSMutableArray *recentEmojis = [self recentEmojis]; + for (int i = 0; i < [recentEmojis count]; ++i) { + if ([recentEmojis[i] isEqualToString:emoji]) { + [recentEmojis removeObjectAtIndex:i]; + } + } + [recentEmojis insertObject:emoji atIndex:0]; + [self setRecentEmojis:recentEmojis]; +} + +// add the emoji to recents +- (void)emojiPageView:(AGEmojiPageView *)emojiPageView didUseEmoji:(NSString *)emoji { + [self setInRecentsEmoji:emoji]; + [self.delegate emojiKeyBoardView:self didUseEmoji:emoji]; +} + +- (void)emojiPageViewDidPressBackSpace:(AGEmojiPageView *)emojiPageView { + [self.delegate emojiKeyBoardViewDidPressBackSpace:self]; +} + +#pragma mark - buttonClick +- (void)sendAction:(UIButton *)sender { + if (self.delegate && [self.delegate respondsToSelector:@selector(emojiKeyBoardView:didUseEmoji:)]) { + [self.delegate emojiKeyBoardView:self didUseEmoji:@"发送"]; + } +} + +@end diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiPageView.h b/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiPageView.h new file mode 100644 index 00000000..a7884135 --- /dev/null +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiPageView.h @@ -0,0 +1,57 @@ +// +// AGEmojiPageView.h +// AGEmojiKeyboard +// +// Created by Ayush on 09/05/13. +// Copyright (c) 2013 Ayush. All rights reserved. +// + +#import + +@protocol AGEmojiPageViewDelegate; + +@interface AGEmojiPageView : UIView + +@property (nonatomic, assign) id delegate; + +/** + Creates and returns an EmojiPageView + + @param backSpaceButtonImage Imge to be used to present the back space button. + @param buttonSize 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 + +/** + 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:(AGEmojiPageView *)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:(AGEmojiPageView *)emojiPageView; + +@end diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiPageView.m b/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiPageView.m new file mode 100644 index 00000000..d3ba025a --- /dev/null +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/AGEmojiKeyboard/AGEmojiPageView.m @@ -0,0 +1,116 @@ +// +// AGEmojiPageView.m +// AGEmojiKeyboard +// +// Created by Ayush on 09/05/13. +// Copyright (c) 2013 Ayush. All rights reserved. +// + +#import "AGEmojiPageView.h" + +#define BACKSPACE_BUTTON_TAG 10 +#define BUTTON_FONT_SIZE 32 + +@interface AGEmojiPageView () + +@property (nonatomic) CGSize buttonSize; +@property (nonatomic) NSMutableArray *buttons; +@property (nonatomic) NSUInteger columns; +@property (nonatomic) NSUInteger rows; +@property (nonatomic) UIImage *backSpaceButtonImage; + +@end + +@implementation AGEmojiPageView + +- (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) { + UIButton *button = [self createButtonAtIndex:i]; + [button setTitle:buttonTexts[i] forState:UIControlStateNormal]; + [self addToViewButton:button]; + } + UIButton *button = [self createButtonAtIndex:self.rows * self.columns - 1]; + [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 diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m index 57a4bb04..9f28491f 100644 --- a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m @@ -9,6 +9,8 @@ #import "LCCKChatBar.h" #import "LCCKChatMoreView.h" #import "LCCKChatFaceView.h" +#import "AGEmojiKeyBoardView.h" + #import "LCCKProgressHUD.h" #import "Mp3Recorder.h" #if __has_include() @@ -24,7 +26,7 @@ NSString *const kLCCKBatchDeleteTextPrefix = @"kLCCKBatchDeleteTextPrefix"; NSString *const kLCCKBatchDeleteTextSuffix = @"kLCCKBatchDeleteTextSuffix"; -@interface LCCKChatBar () +@interface LCCKChatBar () @property (strong, nonatomic) Mp3Recorder *MP3; @property (nonatomic, strong) UIView *inputBarBackgroundView; /**< 输入栏目背景视图 */ @@ -34,6 +36,7 @@ @interface LCCKChatBar () = 2) { +//// [chatText.] +// NSString *subStr = [chatText substringFromIndex:chatText.length-2]; +// if ([(DXFaceView *)self.faceView stringIsFace:subStr]) { +// self.textView.text = [chatText substringToIndex:chatText.length-2]; +// return; +// } +// } +// +// if (chatText.length > 0) { +// self.inputTextView.text = [chatText substringToIndex:chatText.length-1]; +// } + if (chatText.length >= 2) { + self.textView.text = [chatText substringToIndex:chatText.length-2]; + [self textViewDidChange:self.textView]; + } +} + +- (UIImage *)emojiKeyboardView:(AGEmojiKeyboardView *)emojiKeyboardView imageForSelectedCategory:(AGEmojiKeyboardViewCategoryImage)category { + UIImage *img = [UIImage imageNamed:@"[删除]"]; + [img imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + return img; +} + +- (UIImage *)emojiKeyboardView:(AGEmojiKeyboardView *)emojiKeyboardView imageForNonSelectedCategory:(AGEmojiKeyboardViewCategoryImage)category { + UIImage *img = [UIImage imageNamed:@"[删除]"]; + [img imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + return img; +} + +- (UIImage *)backSpaceButtonImageForEmojiKeyboardView:(AGEmojiKeyboardView *)emojiKeyboardView { + UIImage *img = [UIImage imageNamed:@"[删除]"]; + [img imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + return img; +} + #pragma mark - Public Methods - (void)close { @@ -478,6 +545,7 @@ - (void)setup { self.allowTextViewContentOffset = YES; self.MP3 = [[Mp3Recorder alloc] initWithDelegate:self]; [self faceView]; + [self emojiView]; [self moreView]; [self addSubview:self.inputBarBackgroundView]; @@ -597,26 +665,47 @@ - (void)buttonAction:(UIButton *)button { } - (void)showFaceView:(BOOL)show { +// if (show) { +// self.faceView.hidden = NO; +// [UIView animateWithDuration:LCCKAnimateDuration animations:^{ +// [self.faceView mas_updateConstraints:^(MASConstraintMaker *make) { +// make.top.mas_equalTo(self.superview.mas_bottom).offset(-kFunctionViewHeight); +// }]; +// [self.faceView layoutIfNeeded]; +// } completion:nil]; +// +// [self.faceView mas_updateConstraints:^(MASConstraintMaker *make) { +// make.top.mas_equalTo(self.inputBarBackgroundView.mas_bottom); +// }]; +// } else if (self.faceView.superview) { +// self.faceView.hidden = YES; +// [self.faceView mas_remakeConstraints:^(MASConstraintMaker *make) { +// make.width.and.left.mas_equalTo(self); +// make.height.mas_equalTo(kFunctionViewHeight); +// make.top.mas_equalTo(self.mas_bottom); +// }]; +// [self.faceView layoutIfNeeded]; +// } if (show) { - self.faceView.hidden = NO; + self.emojiView.hidden = NO; [UIView animateWithDuration:LCCKAnimateDuration animations:^{ - [self.faceView mas_updateConstraints:^(MASConstraintMaker *make) { + [self.emojiView mas_updateConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.superview.mas_bottom).offset(-kFunctionViewHeight); }]; - [self.faceView layoutIfNeeded]; + [self.emojiView layoutIfNeeded]; } completion:nil]; - - [self.faceView mas_updateConstraints:^(MASConstraintMaker *make) { + + [self.emojiView mas_updateConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.inputBarBackgroundView.mas_bottom); }]; - } else if (self.faceView.superview) { - self.faceView.hidden = YES; - [self.faceView mas_remakeConstraints:^(MASConstraintMaker *make) { + } else if (self.emojiView.superview) { + self.emojiView.hidden = YES; + [self.emojiView mas_remakeConstraints:^(MASConstraintMaker *make) { make.width.and.left.mas_equalTo(self); make.height.mas_equalTo(kFunctionViewHeight); make.top.mas_equalTo(self.mas_bottom); }]; - [self.faceView layoutIfNeeded]; + [self.emojiView layoutIfNeeded]; } } @@ -721,6 +810,17 @@ - (LCCKChatFaceView *)faceView { return _faceView; } +- (AGEmojiKeyboardView *)emojiView { + if (!_emojiView) { + AGEmojiKeyboardView *emojiKeyboardView = [[AGEmojiKeyboardView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 216) dataSource:self]; + emojiKeyboardView.autoresizingMask = UIViewAutoresizingFlexibleHeight; + emojiKeyboardView.delegate = self; + emojiKeyboardView.hidden = YES; + [self addSubview:(_emojiView = emojiKeyboardView)]; + } + return _emojiView; +} + - (LCCKChatMoreView *)moreView { if (!_moreView) { LCCKChatMoreView *moreView = [[LCCKChatMoreView alloc] init]; @@ -811,8 +911,13 @@ - (UIButton *)faceButton { } - (CGFloat)bottomHeight { - if (self.faceView.superview || self.moreView.superview) { - return MAX(self.keyboardSize.height, MAX(self.faceView.frame.size.height, self.moreView.frame.size.height)); +// if (self.faceView.superview || self.moreView.superview) { +// return MAX(self.keyboardSize.height, MAX(self.faceView.frame.size.height, self.moreView.frame.size.height)); +// } else { +// return MAX(self.keyboardSize.height, CGFLOAT_MIN); +// } + if (self.emojiView.superview || self.moreView.superview) { + return MAX(self.keyboardSize.height, MAX(self.emojiView.frame.size.height, self.moreView.frame.size.height)); } else { return MAX(self.keyboardSize.height, CGFLOAT_MIN); } From 3ece32e956e5942d83a68b4f3a7ac5764057067a Mon Sep 17 00:00:00 2001 From: shuq Date: Thu, 26 Oct 2017 11:15:03 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 6148 bytes ChatKit-OC/.DS_Store | Bin 6148 -> 6148 bytes ChatKit-OC/Example/Class/Module/.DS_Store | Bin 0 -> 6148 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 .DS_Store create mode 100644 ChatKit-OC/Example/Class/Module/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ab966488d8ec24e208e80a8286f4152f483ddff8 GIT binary patch literal 6148 zcmeHKyG{c^3>-s>2%40X`vWQXgH=c>3X1#yNJs$*1t|jRtN5;b8smo$(S?G7CK^lj z?0P+Wx+%_Q0JeC4yar|frgTSqdKjCZyN~RwGDf8Hj$1tA4RhS#W>kGV;oJ*WKjDGQ zAN-H?Zu|1O-Q?ZJ$;wIrDIf);fE17de^$VIFKv36s3--bfE4&vz`qZT?$`^5#Q1bD z#0Wr~FdfEq%o4=r31TlC5}Bb{Qi(~m8Zj*C%(trRg+pS}VKsbMJ=tnPv3NS~Z&42G ziHcG{3LGkMp4*xC{}uh0`TvllofMD)C#8T*mh0t$uT;Ht^m5*78~vW{HG8@n*Fj;3 lc1(t0>C4=4+n!!XYu}%mtr4#JErOPCi^h$Q#il?1ndm13>6HC47m&i3^@#`Wx+*x WIr(|%KpDo(g3NbWHnVg5)$v#Z`7&mM-WWL5Su|aJ!JI7ys0RAlu@Bjb+ diff --git a/ChatKit-OC/Example/Class/Module/.DS_Store b/ChatKit-OC/Example/Class/Module/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..39d251dc06e5b8949fafec9b5738de0612c06c60 GIT binary patch literal 6148 zcmeHK%}(Pm5VlK!M6E=SIDoVVOMBqbL!pR@TU6kN1R~Y;z)wk(hz3Ooq-lGoDuox| z0bsAY@E+_#?2B+`#&!{?a0CIGk;dP6JY(0ND^JWA_AD>-bUElov^Y`}dUY!DmzpIpajbr!+#xpwlP8vr^ zd;LxK@Bf!c)FTFnfp5hCFK#(o4cL;dtrMHWS}Q Date: Thu, 26 Oct 2017 11:35:08 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChatKit-OC/.DS_Store | Bin 6148 -> 6148 bytes .../Conversation/View/ChatBar/LCCKChatBar.m | 33 ++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ChatKit-OC/.DS_Store b/ChatKit-OC/.DS_Store index ae2a586bd43ca1af58de50235463535276c5082f..f0378d6f26115daee3d52f9301794ffc4eb664e9 100644 GIT binary patch delta 15 WcmZoMXffE}#l$p&X|oU04p9IoV+79t delta 15 WcmZoMXffE}#l$rI-ew=B9ijj&gaxVq diff --git a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m index 6a8b36f1..674b004d 100644 --- a/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m +++ b/ChatKit/Class/Module/Conversation/View/ChatBar/LCCKChatBar.m @@ -25,6 +25,7 @@ NSString *const kLCCKBatchDeleteTextPrefix = @"kLCCKBatchDeleteTextPrefix"; NSString *const kLCCKBatchDeleteTextSuffix = @"kLCCKBatchDeleteTextSuffix"; +static CGFloat const kLCCKVolumeMaxTimeLength = 15; @interface LCCKChatBar () @@ -432,14 +433,42 @@ - (void)emojiKeyBoardViewDidPressBackSpace:(AGEmojiKeyboardView *)emojiKeyBoardV } } +- (UIColor *)randomColor { + return [UIColor colorWithRed:drand48() + green:drand48() + blue:drand48() + alpha:drand48()]; +} + +- (UIImage *)randomImage { + CGSize size = CGSizeMake(30, 10); + UIGraphicsBeginImageContextWithOptions(size , NO, 0); + + CGContextRef context = UIGraphicsGetCurrentContext(); + UIColor *fillColor = [self randomColor]; + CGContextSetFillColorWithColor(context, [fillColor CGColor]); + CGRect rect = CGRectMake(0, 0, size.width, size.height); + CGContextFillRect(context, rect); + + fillColor = [self randomColor]; + CGContextSetFillColorWithColor(context, [fillColor CGColor]); + CGFloat xxx = 3; + rect = CGRectMake(xxx, xxx, size.width - 2 * xxx, size.height - 2 * xxx); + CGContextFillRect(context, rect); + + UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return img; +} + - (UIImage *)emojiKeyboardView:(AGEmojiKeyboardView *)emojiKeyboardView imageForSelectedCategory:(AGEmojiKeyboardViewCategoryImage)category { - UIImage *img = [UIImage imageNamed:@"[删除]"]; + UIImage *img = [self randomImage]; [img imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; return img; } - (UIImage *)emojiKeyboardView:(AGEmojiKeyboardView *)emojiKeyboardView imageForNonSelectedCategory:(AGEmojiKeyboardViewCategoryImage)category { - UIImage *img = [UIImage imageNamed:@"[删除]"]; + UIImage *img = [self randomImage]; [img imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; return img; }