标签:
// // 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
标签:
原文地址:http://www.cnblogs.com/songxing10000/p/4700861.html