Initial commit

This commit is contained in:
ifish
2017-08-15 16:59:01 +08:00
commit bdc83e07ef
5766 changed files with 423223 additions and 0 deletions
@@ -0,0 +1,78 @@
//
// UMComEditTextView.h
// UMCommunity
//
// Created by umeng on 15/11/11.
// Copyright © 2015年 Umeng. All rights reserved.
//
#import <UIKit/UIKit.h>
@class UMComEditTextView;
@protocol UMComEditTextViewDelegate <NSObject>
@optional;
- (NSArray *)editTextViewDidUpdate:(UMComEditTextView *)textView matchWords:(NSArray *)matchWords;
- (BOOL)editTextView:(UMComEditTextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text complection:(void (^)())block;
- (void)editTextViewDidChangeSelection:(UMComEditTextView *)textView;
- (void)editTextViewDidEndEditing:(UMComEditTextView *)textView;
@end
@interface UMComEditTextView : UITextView
@property (nonatomic, weak) id<UMComEditTextViewDelegate> editDelegate;
@property (nonatomic, strong) NSArray *checkWords;
@property (nonatomic, assign) CGFloat maxTextLenght;
@property (nonatomic, strong) UILabel *placeholderLabel;
@property (nonatomic, copy) NSArray * (^getCheckWords)();
- (instancetype)initWithFrame:(CGRect)frame checkWords:(NSArray *)checkWords regularExStrArray:(NSArray *)regularExStrArray;
- (void)updateEditTextView;
- (NSInteger)getRealTextLength;
//判断text是否大于当前控件的最大限制
-(BOOL)checkMaxLength:(NSString*)text;
@end
@interface UMComHighLightTextUnit : UIResponder
/**
* 文本单元内容
*/
@property (nonatomic,copy ) NSString *text;
/**
* 文本单元字体
*/
@property (nonatomic,strong) UIFont *font;
/**
* 文本单元颜色
*/
@property (nonatomic,strong) UIColor *textColor;
/**
* 文本单元在字符串中的位置
*/
@property (nonatomic,assign) NSRange range;
+ (UMComHighLightTextUnit *)textUnitWithText:(NSString *)text
font:(UIFont *)font
textColor:(UIColor *)color
range:(NSRange)range;
@end
@@ -0,0 +1,421 @@
//
// UMComEditTextView.m
// UMCommunity
//
// Created by umeng on 15/11/11.
// Copyright © 2015年 Umeng. All rights reserved.
//
#import "UMComEditTextView.h"
#import "UMComResouceDefines.h"
#import <UMComFoundation/UMUtils.h>
#import "UMComMutiTextRun.h"
#import <UMComFoundation/UMComKit+String.h>
#import <UMComFoundation/UMComKit+Color.h>
@interface UMComEditTextView () <UITextViewDelegate>
@property (nonatomic, strong) UILabel *noticeLabel;
@property (nonatomic, strong) NSMutableArray *regularExpressionArray;
@end
@implementation UMComEditTextView
{
BOOL isShowTopicNoticeBgView;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [self initWithFrame:frame checkWords:nil regularExStrArray:nil];
if (self) {
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame checkWords:(NSArray *)checkWords regularExStrArray:(NSArray *)regularExStrArray
{
if (UMSYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7")) {
NSTextContainer *container = [[NSTextContainer alloc] initWithSize:CGSizeMake(frame.size.width, frame.size.height)];
container.lineFragmentPadding = 2;
container.size = CGSizeMake(self.frame.size.width, MAXFLOAT);//设置成最大得高度输入多文本滚动
container.widthTracksTextView = YES;
NSTextStorage *textStorage = [[NSTextStorage alloc]init];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[layoutManager addTextContainer:container];
[textStorage addLayoutManager:layoutManager];
self = [super initWithFrame:frame textContainer:container];
//如果有话题则默认添加话题
}else{
self = [super initWithFrame:frame];
}
if (self) {
_regularExpressionArray = [NSMutableArray arrayWithCapacity:regularExStrArray.count];
for (NSString *regex in regularExStrArray) {
NSRegularExpression *regularExpression = [NSRegularExpression
regularExpressionWithPattern:regex
options:NSRegularExpressionCaseInsensitive
error:nil];
if (regularExpression) {
[_regularExpressionArray addObject:regularExpression];
}
}
self.textColor= [UIColor blackColor];
self.font = [UIFont systemFontOfSize:20];
self.delegate = self;
self.checkWords = checkWords;
_noticeLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
//_noticeLabel.backgroundColor = [UIColor clearColor];
_noticeLabel.font = UMComFontNotoSansLightWithSafeSize(14);
_noticeLabel.text = UMComLocalizedString(@"um_com_contentTooLong", @"抱歉,内容过长");
_noticeLabel.textAlignment = NSTextAlignmentCenter;
_noticeLabel.textColor = [UIColor blueColor];
_noticeLabel.backgroundColor = [UIColor lightGrayColor];
_noticeLabel.hidden = YES;
[self addSubview:_noticeLabel];
_placeholderLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, -5, frame.size.width, 40)];
_placeholderLabel.font = UMComFontNotoSansLightWithSafeSize(15);
_placeholderLabel.backgroundColor = [UIColor clearColor];
_placeholderLabel.textColor = [UIColor grayColor];
[self addSubview:_placeholderLabel];
_maxTextLenght = 1000;
}
return self;
}
- (void)updateEditTextView
{
[self textViewDidChange:self];
[self matchWordsWithTextColor:UMComColorWithHexString(FontColorBlue)];
}
#pragma mark - UITextViewDelegate
- (void)textViewDidChangeSelection:(UITextView *)textView
{
[self showPlaceHolderLabelWithTextView:textView];
if (self.editDelegate && [self.editDelegate respondsToSelector:@selector(editTextViewDidChangeSelection:)]) {
[self.editDelegate editTextViewDidChangeSelection:self];
}
}
- (BOOL)textViewShouldEndEditing:(UITextView *)textView
{
return YES;
}
- (void)showPlaceHolderLabelWithTextView:(UITextView *)textView
{
if (textView.text.length > 0 && ![@" " isEqualToString:textView.text]) {
self.placeholderLabel.hidden = YES;
}else{
self.placeholderLabel.hidden = NO;
}
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
if (textView.text.length == 0) {
self.placeholderLabel.hidden = NO;
}
if (UMSYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"6")) {
[self matchWordsWithTextColor:UMComColorWithHexString(FontColorBlue)];
}
if (self.editDelegate && [self.editDelegate respondsToSelector:@selector(editTextViewDidEndEditing:)]) {
[self.editDelegate editTextViewDidEndEditing:self];
}
}
- (void)hiddenTextView
{
self.noticeLabel.hidden = YES;
}
-(void) doShowPlaceHolderLabel
{
self.noticeLabel.hidden = NO;
//显示noticeLabel的位置
self.noticeLabel.frame = CGRectMake(self.contentOffset.x,self.contentOffset.y, self.bounds.size.width, self.bounds.size.height);
[self performSelector:@selector(hiddenTextView) withObject:nil afterDelay:0.8f];
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
//判断text的长度大于零,避免删除的情况不能编辑
//if ([self getRealTextLength] > self.maxTextLenght && text.length > 0) {
if (self.maxTextLenght <= 0) {
return NO;
}
//当时删除的时候text为空,以此方法判断是否用户点击删除按键
if ([text isEqualToString:@""]) {
return YES;
}
NSInteger markLength = 0;//标记的长度
UITextRange* curMarkText = textView.markedTextRange;
if (curMarkText) {
markLength = [self offsetFromPosition:curMarkText.start toPosition:curMarkText.end];
}
NSInteger curLength = 0.f;
NSInteger nextLength = 0.f;
curLength = [UMComKit getStringLengthWithString:self.text];//当前长度(用于判断表情)
nextLength = [UMComKit getStringLengthWithString:text];//即将要输入的长度(用于判断表情)
curLength -= markLength;
if (curLength + nextLength > self.maxTextLenght ) {
self.noticeLabel.hidden = NO;
//显示noticeLabel的位置
self.noticeLabel.frame = CGRectMake(self.contentOffset.x,self.contentOffset.y, self.bounds.size.width, self.bounds.size.height);
[self performSelector:@selector(hiddenTextView) withObject:nil afterDelay:0.8f];
return NO;
}else{
self.noticeLabel.hidden = YES;
}
if (self.editDelegate && [self.editDelegate respondsToSelector:@selector(editTextView:shouldChangeTextInRange:replacementText:complection:)]) {
__weak typeof(self) weakSelf = self;
return [self.editDelegate editTextView:self shouldChangeTextInRange:range replacementText:text complection:^{
[weakSelf textViewDidChange:weakSelf];
}];
}
return YES;
}
- (void)textViewDidChange:(UITextView *)textView
{
if (UMSYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7")) {
[self matchWordsWithTextColor:UMComColorWithHexString(FontColorBlue)];
}
[self showPlaceHolderLabelWithTextView:textView];
//http://stackoverflow.com/questions/19948394/textviewdidchange-crashes-in-ios-7
if (textView.markedTextRange) {
//联想输入的时候,不需要计算其长度
return;
}
//此处判断是否达到最大长度限制
NSInteger curLength = [UMComKit getStringLengthWithString:self.text];//当前长度(用于判断表情)
if (curLength > self.maxTextLenght && self.maxTextLenght > 0) {
[self doShowPlaceHolderLabel];
self.text = [self.text substringToIndex:self.maxTextLenght];
}
}
#pragma mark - textUpdata
- (void)matchWordsWithTextColor:(UIColor *)color
{
if (self.text.length == 0) {
return;
}
if (self.getCheckWords) {
self.checkWords = self.getCheckWords();
}
__weak typeof(self) weakSelf = self;
if (UMSYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7")) {
[self updateiOS7AndLaterTextWithColor:color checkWords:self.checkWords completion:^(NSArray *matchWords) {
if (weakSelf.editDelegate && [weakSelf.editDelegate respondsToSelector:@selector(editTextViewDidUpdate:matchWords:)]) {
weakSelf.checkWords = [weakSelf.editDelegate editTextViewDidUpdate:weakSelf matchWords:[matchWords valueForKeyPath:@"text"]];
}
}];
}else{
[self creatHighLightWithFont:self.font color:color checkWords:self.checkWords complection:^(NSArray * matchWords, NSMutableAttributedString *attributedString) {
if (self.editDelegate && [self.editDelegate respondsToSelector:@selector(editTextViewDidUpdate:matchWords:)]) {
[self.editDelegate editTextViewDidUpdate:weakSelf matchWords:[matchWords valueForKeyPath:@"text"]];
}
weakSelf.attributedText = attributedString;
}];
}
[self reloadInputViews];
}
- (NSArray *)rangeArrayOfSubString:(NSString *)subString originStrin:(NSString *)originString lastRangeArray:(NSArray *)lastRangeArray
{
if (originString.length >= subString.length) {
NSMutableArray *rangeArray = [NSMutableArray array];
if (lastRangeArray.count > 0) {
[rangeArray addObjectsFromArray:lastRangeArray];
}
NSRange macthRange = [originString rangeOfString:subString];
if (macthRange.length > 0) {
NSValue *rangeValue = [NSValue valueWithRange:macthRange];
[rangeArray addObject:rangeValue];
[self rangeArrayOfSubString:subString originStrin:[originString substringFromIndex:macthRange.length - 1] lastRangeArray:rangeArray];
}
return rangeArray;
}
return lastRangeArray;
}
- (void)updateiOS7AndLaterTextWithColor:(UIColor *)color
checkWords:(NSArray *)checkWords
completion:(void (^) (NSArray *matchWords))block
{
[self.textStorage addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, self.textStorage.length)];
NSMutableArray *HLTextUnits = [NSMutableArray array];
for (NSString *checkWord in checkWords) {
NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:checkWord options:NSRegularExpressionDotMatchesLineSeparators error:nil];
NSArray *matchs = [regular matchesInString:self.textStorage.string
options:0
range:NSMakeRange(0, [self.textStorage.string length])];
for (NSTextCheckingResult *match in matchs) {
[self.textStorage addAttribute:NSForegroundColorAttributeName value:color range:match.range];
if (![[HLTextUnits valueForKeyPath:@"text"] containsObject:checkWord]) {
UMComHighLightTextUnit *textUnit = [UMComHighLightTextUnit textUnitWithText:checkWord font:self.font textColor:color range:match.range];
[HLTextUnits addObject:textUnit];
}
}
}
if (block) {
block(HLTextUnits);
}
}
//产生高亮字体
- (void)creatHighLightWithFont:(UIFont *)font color:(UIColor *)color checkWords:(NSArray *)checkWords complection:(void(^)(NSArray *checkWords ,NSMutableAttributedString *attributedString))block
{
if (self.text.length == 0) {
return;
}
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:self.text];
self.attributedText = attributedString;
[attributedString addAttribute:NSForegroundColorAttributeName value:(id)[UIColor blackColor] range:NSMakeRange(0, attributedString.length-1)];
NSString *string = attributedString.string;
NSMutableArray *HLTextUnits = [NSMutableArray array];
for (NSRegularExpression *regularExpression in _regularExpressionArray) {
NSArray *matchs = [regularExpression matchesInString:string options:0 range:NSMakeRange(0, string.length)];
if ([regularExpression.pattern isEqualToString:UrlRelerSring]) {
for (NSTextCheckingResult *match in matchs)
{
NSString* matchText = [self.textStorage.string substringWithRange:match.range];
[attributedString addAttribute:(id)NSForegroundColorAttributeName value:(id)color range:match.range];
if (![[HLTextUnits valueForKeyPath:@"text"] containsObject:matchText]) {
UMComHighLightTextUnit *textUnit = [UMComHighLightTextUnit textUnitWithText:matchText font:self.font textColor:color range:match.range];
[HLTextUnits addObject:textUnit];
}
}
}else{
for (NSTextCheckingResult *match in matchs)
{
NSRange matchRange = NSMakeRange(match.range.location, match.range.length);
NSString *matchText = [string substringWithRange:matchRange];
for (NSString *checkWord in checkWords) {
if ([matchText isEqualToString:checkWord]) {
[attributedString addAttribute:(id)NSForegroundColorAttributeName value:(id)color range:match.range];
if (![[HLTextUnits valueForKeyPath:@"text"] containsObject:matchText]) {
UMComHighLightTextUnit *textUnit = [UMComHighLightTextUnit textUnitWithText:matchText font:self.font textColor:color range:match.range];
[HLTextUnits addObject:textUnit];
}
}
}
}
}
}
[attributedString addAttribute:NSFontAttributeName value:(id)font range:NSMakeRange(0, attributedString.length)];
if (block) {
block(HLTextUnits, attributedString);
}
}
- (NSInteger)getRealTextLength
{
NSInteger topicAndUserLength = 0;
NSMutableArray *matchs = [NSMutableArray array];
for (NSRegularExpression *regularExpression in _regularExpressionArray) {
NSArray *subMatchs = [regularExpression matchesInString:self.text options:0 range:NSMakeRange(0, self.text.length)];
if (subMatchs.count > 0) {
[matchs addObjectsFromArray:subMatchs];
}
}
NSArray *checkWords = self.checkWords;
for (NSTextCheckingResult *match in matchs)
{
for (NSString *item in checkWords) {
NSRange matchRange = NSMakeRange(match.range.location, match.range.length);
NSString *matchText = [self.text substringWithRange:matchRange];
if ([item isEqualToString:matchText]) {
topicAndUserLength += [UMComKit getStringLengthWithString:matchText];
}
}
}
NSString *realTextString = [self.text stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSInteger realTextLength = [UMComKit getStringLengthWithString:realTextString] - topicAndUserLength;
return realTextLength;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
-(BOOL)checkMaxLength:(NSString*)text
{
if (!text) {
return NO;
}
NSInteger curLength = [UMComKit getStringLengthWithString:text];
if (curLength> self.maxTextLenght ) {
self.noticeLabel.hidden = NO;
//显示noticeLabel的位置
self.noticeLabel.frame = CGRectMake(self.contentOffset.x,self.contentOffset.y, self.bounds.size.width, self.bounds.size.height);
[self performSelector:@selector(hiddenTextView) withObject:nil afterDelay:0.8f];
return YES;
}
else{
return NO;
}
}
@end
@implementation UMComHighLightTextUnit
- (instancetype)initWithTextUnitWithText:(NSString *)text
font:(UIFont *)font
textColor:(UIColor *)color
range:(NSRange)range
{
self = [super init];
if (self) {
self.text = text;
self.textColor = color;
self.font = font;
self.range = range;
}
return self;
}
+ (UMComHighLightTextUnit *)textUnitWithText:(NSString *)text
font:(UIFont *)font
textColor:(UIColor *)color
range:(NSRange)range
{
UMComHighLightTextUnit *textUnit = [[UMComHighLightTextUnit alloc]initWithTextUnitWithText:text font:font textColor:color range:range];
return textUnit;
}
@end