//
// SubmitEvaluationVC.m
// CarPool
//
// Created by apollo on 15/6/17.
//
//
#import "CPSubmitEvaluationVC.h"
#import "CPMineDef.h"
#import "Style_HeaderLabel.h"
#import "CPEvaluationButton.h"
#import "CPEmotionKeyboard.h"
#import "CPEmotionTextView.h"
#import "CPEmotionKeyboardToolbar.h"
@interface CPSubmitEvaluationVC ()<UITextViewDelegate, CPEmotionKeyboardToolbarDelegate>
{
NSRange selectedRange;
}
@property (weak, nonatomic) IBOutlet UIButton *submitEvaluationBtn;/**< 提交评价按钮 */
@property (weak, nonatomic) IBOutlet Style_HeaderLabel *naviTitleLabel;/**< 导航标题 */
@property (weak, nonatomic) IBOutlet CPEmotionTextView *evaluationTextView; /**< 输入评价内容的textView */
@property (weak, nonatomic) IBOutlet CPEvaluationButton *goodEvaluationBtn;
@property (weak, nonatomic) IBOutlet CPEvaluationButton *midleEvaluationBtn;
@property (weak, nonatomic) IBOutlet CPEvaluationButton *badEvaluationBtn;
@property (weak, nonatomic) IBOutlet UILabel *inputNumberTipsLabel; /**< 输入数量提示 */
@property (nonatomic, assign) EvaluationRoleType evaluationRoleType;
@property (strong, nonatomic) CPRouteOrderEntity *order;
@property (strong, nonatomic) UIButton *currentSelectedBtn;
/** 点击任何一个评价按钮事件 */
- (IBAction)allEvaluationBtnClick:(UIButton *)sender;
- (IBAction)submitEvaluationBtnClick;/**< 提交评价事件 */
- (IBAction)returnBtnClick;
@property (nonatomic, strong) CPEmotionKeyboard *keyboard;
@property (nonatomic, strong) CPEmotionKeyboardToolbar *toolbar;
@property (nonatomic, strong) CPEmotionKeyboardToolbar *tempToolbar;
@property (nonatomic, assign, getter = isChangingKeyboard) BOOL changingKeyboard;
@end
@implementation CPSubmitEvaluationVC
- (instancetype)initWithEvaluationRoleType:(EvaluationRoleType)type order:(CPRouteOrderEntity *)order {
self = [super init];
if (self) {
_evaluationRoleType = type;
_order = order;
}
return self;
}
#pragma mark - life cycle
- (void)viewDidLoad {
[super viewDidLoad];
self.goodEvaluationBtn.selected = YES;// 默认好评
self.currentSelectedBtn = self.goodEvaluationBtn;
if (_evaluationRoleType == EvaluationRoleTypeDriver) {
_naviTitleLabel.text = @"评价车主";
_evaluationTextView.placehoder = @"给车主一些感谢及评价吧~";
}
else if (_evaluationRoleType == EvaluationRoleTypePassenger) {
_naviTitleLabel.text = @"评价乘客";
_evaluationTextView.placehoder = @"评价一下乘客吧~";
}
[_submitEvaluationBtn blueButton];
// 添加输入框
[self setupTextView];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.evaluationTextView becomeFirstResponder];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.evaluationTextView resignFirstResponder];
}
/**
* 添加输入框
*/
- (void)setupTextView
{
// emoji
self.evaluationTextView.alwaysBounceVertical = YES; // 垂直方向上永远有弹簧效果
self.evaluationTextView.delegate = self;
// 设置键盘上面的工具条
// self.textView.inputView 设置键盘
CPEmotionKeyboardToolbar *toolbar = [[CPEmotionKeyboardToolbar alloc] init];
toolbar.width = self.view.width;
toolbar.height = 44;
toolbar.delegate = self;
self.evaluationTextView.inputAccessoryView = toolbar;
self.toolbar = toolbar;
CPEmotionKeyboardToolbar *tempToolbar = [[CPEmotionKeyboardToolbar alloc] init];
tempToolbar.height = toolbar.height;
tempToolbar.delegate = self;
tempToolbar.width = self.view.width;
tempToolbar.y = self.view.height - tempToolbar.height;
// [self.view addSubview:tempToolbar];
self.tempToolbar = tempToolbar;
// 监听键盘内部删除按钮点击的通知
[kNoteCenter addObserver:self.evaluationTextView selector:@selector(deleteBackward) name:SXDeleteButtonDidClickNotification object:nil];
// 监听键盘内部表情按钮点击的通知
[kNoteCenter addObserver:self selector:@selector(emotionButtonClick:) name:SXEmotionButtonDidClickNotification object:nil];
// 4.监听键盘
// 键盘的frame(位置)即将改变, 就会发出UIKeyboardWillChangeFrameNotification
// 键盘即将弹出, 就会发出UIKeyboardWillShowNotification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
// 键盘即将隐藏, 就会发出UIKeyboardWillHideNotification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)emotionButtonClick:(NSNotification *)note
{
#if 0
// 插入表情
[self.evaluationTextView insertEmotion:note.userInfo[SXClickedEmotion]];
#else
// 插入表情对应的文字
[self.evaluationTextView insertEmotionText:[note.userInfo[SXClickedEmotion] name]];
#endif
// 文字改变
[self textViewDidChange:self.evaluationTextView];
// plist
// preference nsuserdefault
// nscoding nskeyedarchived
}
- (void)deleteButtonDidClick
{
[self.evaluationTextView deleteBackward];
}
- (void)dealloc
{
[kNoteCenter removeObserver:self];
}
#pragma mark - 键盘处理
/**
* 键盘即将隐藏
*/
- (void)keyboardWillHide:(NSNotification *)note
{
if (self.isChangingKeyboard) return;
// 1.键盘弹出需要的时间
CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// 2.动画
[UIView animateWithDuration:duration animations:^{
self.toolbar.transform = CGAffineTransformIdentity;
}];
}
/**
* 键盘即将弹出
*/
- (void)keyboardWillShow:(NSNotification *)note
{
// 1.键盘弹出需要的时间
CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// 2.动画
[UIView animateWithDuration:duration animations:^{
// 取出键盘高度
CGRect keyboardF = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardH = keyboardF.size.height;
self.toolbar.transform = CGAffineTransformMakeTranslation(0, - keyboardH);
}];
}
#pragma mark - CPComposeToolbarDelegate
- (void)toolbar:(CPEmotionKeyboardToolbar *)toolbar didClickButton:(CPEmotionKeyboardToolbarButtonType)buttonType {
switch (buttonType) {
case CPEmotionKeyboardToolbarButtonTypeCamera:
// [self openCamera];
break;
case CPEmotionKeyboardToolbarButtonTypePicture:
// [self openAlbum];
break;
case CPEmotionKeyboardToolbarButtonTypeMention:
NSLog(@"@");
break;
case CPEmotionKeyboardToolbarButtonTypeTrend:
NSLog(@"#");
break;
case CPEmotionKeyboardToolbarButtonTypeEmotion:
[self switchKeyboard];
break;
}
}
/**
* 切换键盘
*/
- (void)switchKeyboard
{
// 正在切换键盘
self.changingKeyboard = YES;
if (self.evaluationTextView.inputView) { // 当前显示的是自定义键盘,切换为系统自带的键盘
self.evaluationTextView.inputView = nil;
// 显示表情图片
[self.toolbar switchEmotionButtonImage:YES];
[self.tempToolbar switchEmotionButtonImage:YES];
} else { // 当前显示的是系统自带的键盘,切换为自定义键盘
// 如果临时更换了文本框的键盘,一定要重新打开键盘
self.evaluationTextView.inputView = self.keyboard;
// 不显示表情图片
[self.toolbar switchEmotionButtonImage:NO];
[self.tempToolbar switchEmotionButtonImage:NO];
}
// 关闭键盘
[self.evaluationTextView resignFirstResponder];
#warning 记录是否正在更换键盘
// 更换完毕完毕
self.changingKeyboard = NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 打开键盘
[self.evaluationTextView becomeFirstResponder];
});
// [self.evaluationTextView resignFirstResponder];
//
// if (self.evaluationTextView.inputView) { // 正在使用自定义键盘,切换为系统键盘
// self.evaluationTextView.inputView = nil;
//
// // 显示表情图片
// [self.toolbar switchEmotionButtonImage:YES];
// [self.tempToolbar switchEmotionButtonImage:YES];
// } else { // 正在使用系统键盘,切换为自定义键盘
// self.evaluationTextView.inputView = self.keyboard;
//
// // 显示键盘图片
// [self.toolbar switchEmotionButtonImage:NO];
// [self.tempToolbar switchEmotionButtonImage:NO];
// }
//
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// [self.evaluationTextView becomeFirstResponder];
// });
}
#pragma mark - UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
UITextRange *selectedRange1 = [textView markedTextRange];
//获取高亮部分
UITextPosition *pos = [textView positionFromPosition:selectedRange1.start offset:0];
//获取高亮部分内容
//NSString * selectedtext = [textView textInRange:selectedRange];
//如果有高亮且当前字数开始位置小于最大限制时允许输入
if (selectedRange1 && pos) {
NSInteger startOffset = [textView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange1.start];
NSInteger endOffset = [textView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange1.end];
NSRange offsetRange = NSMakeRange(startOffset, endOffset - startOffset);
if (offsetRange.location < MAX_LIMIT_NUMS) {
return YES;
}
else
{
return NO;
}
}
NSString *comcatstr = [textView.text stringByReplacingCharactersInRange:range withString:text];
// NSInteger caninputlen = MAX_LIMIT_NUMS - comcatstr.length;
NSInteger caninputlen = MAX_LIMIT_NUMS - [comcatstr getStringLengthIfIsEmojiLengthAsOne];
if (caninputlen >= 0)
{
return YES;
}
else
{
// NSInteger len = text.length + caninputlen;
NSInteger len = [text getStringLengthIfIsEmojiLengthAsOne] + caninputlen;
//防止当text.length + caninputlen < 0时,使得rg.length为一个非法最大正数出错
NSRange rg = {0,MAX(len,0)};
if (rg.length > 0)
{
NSString *s = @"";
//判断是否只普通的字符或asc码(对于中文和表情返回NO)
BOOL asc = [text canBeConvertedToEncoding:NSASCIIStringEncoding];
if (asc) {
s = [text substringWithRange:rg];//因为是ascii码直接取就可以了不会错
}
else
{
__block NSInteger idx = 0;
__block NSString *trimString = @"";//截取出的字串
//使用字符串遍历,这个方法能准确知道每个emoji是占一个unicode还是两个
[text enumerateSubstringsInRange:NSMakeRange(0, [text length])
options:NSStringEnumerationByComposedCharacterSequences
usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {
// NSInteger steplen = substring.length;
NSInteger steplen = [substring getStringLengthIfIsEmojiLengthAsOne];
if (idx >= rg.length) {
*stop = YES; //取出所需要就break,提高效率
return ;
}
trimString = [trimString stringByAppendingString:substring];
idx = idx + steplen;
}];
s = trimString;
}
__block BOOL hasAttachment = NO;
[textView.attributedText enumerateAttributesInRange:NSMakeRange(0, textView.attributedText.length) options:NSAttributedStringEnumerationReverse usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
if(attrs[@"NSAttachment"])
{
*stop = YES;
hasAttachment = YES;
}
}];
if (textView.text.length > MAX_LIMIT_NUMS) {
kToastWithString(@"输入已达上限")
if (hasAttachment) {
[textView.attributedText attributedSubstringFromRange:NSMakeRange(0, MAX_LIMIT_NUMS)];
} else {
//rang是指从当前光标处进行替换处理(注意如果执行此句后面返回的是YES会触发didchange事件)
[textView setText:[textView.text stringByReplacingCharactersInRange:range withString:s]];
}
}
//既然是超出部分截取了,哪一定是最大限制了。
self.inputNumberTipsLabel.text = [NSString stringWithFormat:@"%d/%ld",0,(long)MAX_LIMIT_NUMS];
}
if (textView.text.length >= MAX_LIMIT_NUMS) {
kToastWithString(@"输入已达上限")
}
return NO;
}
}
- (void)textViewDidChange:(UITextView *)textView
{
// 占位文本显示与否
_submitEvaluationBtn.enabled = self.evaluationTextView.hasText;
UITextRange *selectedRange1 = [textView markedTextRange];
//获取高亮部分
UITextPosition *pos = [textView positionFromPosition:selectedRange1.start offset:0];
//如果在变化中是高亮部分在变,就不要计算字符了
if (selectedRange1 && pos) {
return;
}
NSString *nsTextContent = textView.text;
// NSInteger existTextNum = nsTextContent.length;
NSInteger existTextNum = [nsTextContent getStringLengthIfIsEmojiLengthAsOne];
if (existTextNum >= MAX_LIMIT_NUMS)
{
kToastWithString(@"输入已达上限")
__block BOOL hasAttachment = NO;
[textView.attributedText enumerateAttributesInRange:NSMakeRange(0, textView.attributedText.length) options:NSAttributedStringEnumerationReverse usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
if(attrs[@"NSAttachment"])
{
*stop = YES;
hasAttachment = YES;
}
}];
if (hasAttachment) {
textView.attributedText = [textView.attributedText attributedSubstringFromRange:NSMakeRange(0, MAX_LIMIT_NUMS + [textView.text emojiCount])];
} else {
//截取到最大位置的字符(由于超出截部分在should时被处理了所在这里这了提高效率不再判断)
NSString *s = [nsTextContent substringToIndex:(MAX_LIMIT_NUMS + [textView.text emojiCount])];
[textView setText:s];
}
}
//不让显示负数 口口日
self.inputNumberTipsLabel.text = [NSString stringWithFormat:@"%tu/%tu",MAX(0,MAX_LIMIT_NUMS - existTextNum),MAX_LIMIT_NUMS];
}
//- (void)textViewDidChange:(UITextView *)textView
//{
//
// _submitEvaluationBtn.enabled = self.evaluationTextView.hasText;
//
// if ([textView.text hasPrefix:@"\n"]) {
// if (textView.text.length == 1) {
// _evaluationTextView.text = @"";
//
// }else{
// _evaluationTextView.text = [textView.text substringFromIndex:1];
//
// }
// }
//
// UITextRange * selectedRang = [textView markedTextRange];
//
// if(selectedRang == nil || selectedRang.empty)
// {
// if(textView.text.length > MAX_LIMIT_NUMS)
// {
// [self showToast:@"输入已达到上限"];
// textView.text = [textView.text substringToIndex:MAX_LIMIT_NUMS];
// }
//
// }
//}
#pragma mark - event response
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.view endEditing:YES];
}
- (IBAction)submitEvaluationBtnClick {
[self.view endEditing:YES];
NSNumber *evaluationN = @0; /**< 好评级别 */
if([_currentSelectedBtn.currentTitle isEqualToString:@"好评"]) {
evaluationN = @0;
} else if([_currentSelectedBtn.currentTitle isEqualToString:@"中评"]) {
evaluationN = @1;
} else if([_currentSelectedBtn.currentTitle isEqualToString:@"差评"]) {
evaluationN = @2;
}
CPRouteReqComment *para = [[CPRouteReqComment alloc] init];
para.order_id = self.order.order_id;
para.content = _evaluationTextView.emotionText;
para.level = evaluationN;
if (!self.order)
{
kToastWithString(@"未加载订单")
return;
}
[kCommentEngine commentOrder:para orderInf:self.order
async:^(CPRouteReqComment *commentPara, UUError *error) {
if ([error isSuccess])
{
kToastWithString(@"评价成功")
[self returnBtnClick];
}
else if ([error isNetError])
{
kToastNetError
}
else
{
kToastErrorDes
if ([error errorCode] == 422) {
kToastWithString(@"订单状态错误")
}
}
}];
}
- (IBAction)returnBtnClick {
if ([self getObjectForCalss:NSClassFromString(@"CPCarPoolingFeeVC")]) { // 如果是从CPCarPoolingFeeVC跳转过来
[self popToCell:[self class] index:-2 animated:YES];
} else { // 正常返回
[self returnLastCell:YES];
}
}
- (IBAction)allEvaluationBtnClick:(UIButton *)sender {
if ([sender isEqual:self.currentSelectedBtn]) {
return;
}
sender.selected = YES;
self.currentSelectedBtn.selected = NO;
self.currentSelectedBtn = sender;
}
#pragma mark - getters and setters
- (CPEmotionKeyboard *)keyboard
{
if (!_keyboard) {
self.keyboard = [[CPEmotionKeyboard alloc] init];
self.keyboard.width = SCREEN_WIDTH;
self.keyboard.height = 216;
}
return _keyboard;
}
@end