Skip to content

Commit

Permalink
Merge pull request #9 from molon/molon
Browse files Browse the repository at this point in the history
pod 1.7
  • Loading branch information
molon committed Sep 24, 2015
2 parents b033d01 + 33f8071 commit eefb679
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 27 deletions.
2 changes: 2 additions & 0 deletions Classes/MLExpressionManager.h
Expand Up @@ -26,5 +26,7 @@
+ (NSAttributedString*)expressionAttributedStringWithString:(id)string expression:(MLExpression*)expression;
//给一个str数组,返回其对应的表情attrStr数组,顺序一致
+ (NSArray *)expressionAttributedStringsWithStrings:(NSArray*)strings expression:(MLExpression*)expression;
//同上,但是以回调方式返回
+ (void)expressionAttributedStringsWithStrings:(NSArray*)strings expression:(MLExpression*)expression callback:(void(^)(NSArray *result))callback;

@end
32 changes: 30 additions & 2 deletions Classes/MLExpressionManager.m
Expand Up @@ -100,8 +100,6 @@ - (NSRegularExpression*)expressionRegularExpressionWithRegex:(NSString*)regex
//多线程转表情attrStr
+ (NSArray *)expressionAttributedStringsWithStrings:(NSArray*)strings expression:(MLExpression*)expression
{
//由于MLExpression本身是只读的,而且其属性都是线程安全的,所以这里可以直接用

NSMutableDictionary *results = [NSMutableDictionary dictionaryWithCapacity:strings.count];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
Expand All @@ -126,6 +124,36 @@ + (NSArray *)expressionAttributedStringsWithStrings:(NSArray*)strings expression
return resultArr;
}

+ (void)expressionAttributedStringsWithStrings:(NSArray*)strings expression:(MLExpression*)expression callback:(void(^)(NSArray *result))callback
{
NSMutableDictionary *results = [NSMutableDictionary dictionaryWithCapacity:strings.count];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
for (id str in strings) {
dispatch_group_async(group, queue, ^{
NSAttributedString *result = [MLExpressionManager expressionAttributedStringWithString:str expression:expression];

@synchronized(results){
results[str] = result;
}
});
}

dispatch_group_notify(group, queue, ^{
//重新排列
NSMutableArray *resultArr = [NSMutableArray arrayWithCapacity:results.count];
for (id str in strings) {
[resultArr addObject:results[str]];
}
dispatch_async(dispatch_get_main_queue(), ^{
if (callback) {
callback(resultArr);
}
});
});
}

+ (NSAttributedString*)expressionAttributedStringWithString:(id)string expression:(MLExpression*)expression {
NSAssert(expression&&[expression isValid], @"expression invalid");
NSAssert([string isKindOfClass:[NSString class]]||[string isKindOfClass:[NSAttributedString class]], @"string非字符串. %@",string);
Expand Down
60 changes: 41 additions & 19 deletions Classes/MLLabel.m
Expand Up @@ -58,8 +58,10 @@ @interface MLLabel()<NSLayoutManagerDelegate>

@property (nonatomic, strong) MLLabelStylePropertyRecord *styleRecord;

//为什么需要这个,是因为setAttributedText之后内部可能会对其进行了改动,然后例如再次更新style属性,然后更新绘制会出问题。索性都以记录的为准。
@property (nonatomic, strong) NSAttributedString *lastAttributedText;
//为什么需要这个,是因为setAttributedText之后内部可能会对其进行了改动,然后例如再次更新style属性,然后更新绘制会出问题。索性都以记录的最原始的为准。
@property (nonatomic, copy) NSAttributedString *lastAttributedText;
//读取的时候需要
@property (nonatomic, copy) NSString *lastText;

@end

Expand Down Expand Up @@ -94,8 +96,11 @@ - (void)commonInit
[self.layoutManager addTextContainer:self.textContainer];

//label helper相关
self.lastTextType = MLLastTextTypeNormal;
self.lastAttributedText = self.attributedText;
if ([super attributedText]) {
self.attributedText = [super attributedText];
}else{
self.text = [super text];
}

//kvo 监视style属性
for (NSString *key in kStylePropertyNames()) {
Expand Down Expand Up @@ -173,15 +178,32 @@ - (MLLabelStylePropertyRecord *)styleRecord
return _styleRecord;
}

- (NSAttributedString *)attributedText
{
return _lastTextType==MLLastTextTypeAttributed?_lastAttributedText:[self attributedTextForTextStorageFromLabelProperties];
}

- (NSString*)text
{
return _lastTextType==MLLastTextTypeAttributed?_lastAttributedText.string:_lastText;
}

#pragma mark - set text
- (void)setLastTextType:(MLLastTextType)lastTextType
{
_lastTextType = lastTextType;
//重置下
self.lastText = nil;
self.lastAttributedText = nil;
}

- (void)setText:(NSString *)text
{
NSAssert(!text||[text isKindOfClass:[NSString class]], @"text must be NSString");

[super setText:text];

self.lastTextType = MLLastTextTypeNormal;
self.lastText = text;
// [super setText:text];

[_textStorage setAttributedString:[self attributedTextForTextStorageFromLabelProperties]];

Expand All @@ -193,10 +215,10 @@ - (void)setAttributedText:(NSAttributedString *)attributedText
{
NSAssert(!attributedText||[attributedText isKindOfClass:[NSAttributedString class]], @"text must be NSAttributedString");

[super setAttributedText:attributedText];
self.lastTextType = MLLastTextTypeAttributed;
self.lastAttributedText = attributedText;

self.lastTextType = MLLastTextTypeAttributed;
// [super setAttributedText:attributedText];

[_textStorage setAttributedString:[self attributedTextForTextStorageFromLabelProperties]];

Expand All @@ -217,7 +239,7 @@ - (CGSize)textContainerSizeWithBoundsSize:(CGSize)size
- (void)reSetText
{
if (_lastTextType == MLLastTextTypeNormal) {
self.text = self.text;
self.text = _lastText;
}else{
self.attributedText = _lastAttributedText;
}
Expand All @@ -228,24 +250,24 @@ - (void)reSetText
*/
- (NSMutableAttributedString*)attributedTextForTextStorageFromLabelProperties
{
if (self.lastTextType==MLLastTextTypeNormal) {
if (!self.text) {
if (_lastTextType==MLLastTextTypeNormal) {
if (!_lastText) {
return [[NSMutableAttributedString alloc]initWithString:@""];
}

//根据text和label默认的一些属性得到attributedText,实际上,在[super setText:xxx]之后,这种self.attributedText也会跟随改变成这种的,不过直接拿来用会有问题,这里我们自己搞一份一样的。
return [[NSMutableAttributedString alloc] initWithString:self.text attributes:[self attributesFromLabelProperties]];
//根据text和label默认的一些属性得到attributedText
return [[NSMutableAttributedString alloc] initWithString:_lastText attributes:[self attributesFromLabelProperties]];
}

if (!self.lastAttributedText) {
if (!_lastAttributedText) {
return [[NSMutableAttributedString alloc]initWithString:@""];
}

//遍历并且添加Label默认的属性
NSMutableAttributedString *newAttrStr = [[NSMutableAttributedString alloc]initWithString:self.lastAttributedText.string attributes:[self attributesFromLabelProperties]];
NSMutableAttributedString *newAttrStr = [[NSMutableAttributedString alloc]initWithString:_lastAttributedText.string attributes:[self attributesFromLabelProperties]];

//TODO: 这里在属性多的时候比较耗费性能,回头得想个解决方案
[self.lastAttributedText enumerateAttributesInRange:NSMakeRange(0, newAttrStr.length) options:0 usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
[_lastAttributedText enumerateAttributesInRange:NSMakeRange(0, newAttrStr.length) options:0 usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
if (attrs.count>0) {
// [newAttrStr removeAttributes:[attrs allKeys] range:range];
[newAttrStr addAttributes:attrs range:range];
Expand All @@ -257,7 +279,7 @@ - (NSMutableAttributedString*)attributedTextForTextStorageFromLabelProperties
- (NSDictionary *)attributesFromLabelProperties
{
//颜色
UIColor *color = _styleRecord.textColor;
UIColor *color = self.styleRecord.textColor;
if (!_styleRecord.enabled)
{
color = [UIColor lightGrayColor];
Expand Down Expand Up @@ -487,10 +509,10 @@ - (void)drawTextInRect:(CGRect)rect
//因为label是默认垂直居中的,所以需要根据实际绘制区域的bounds来调整出居中的offset
textOffset = [self textOffsetWithTextSize:drawBounds.size];

if (self.doBeforeDrawingTextBlock) {
if (_doBeforeDrawingTextBlock) {
//而实际上drawBounds的宽度可能不是我们想要的,我们想要的是_textContainer的宽度,但是高度需要是真实绘制高度
CGSize drawSize = CGSizeMake(_textContainer.size.width, drawBounds.size.height);
self.doBeforeDrawingTextBlock(rect,textOffset,drawSize);
_doBeforeDrawingTextBlock(rect,textOffset,drawSize);
}

//绘制文字
Expand Down
2 changes: 1 addition & 1 deletion Classes/NSString+MLExpression.m
Expand Up @@ -12,7 +12,7 @@ @implementation NSString (MLExpression)

- (NSAttributedString*)expressionAttributedStringWithExpression:(MLExpression*)expression;
{
return [MLExpressionManager expressionAttributedStringWithString:self expression:(MLExpression*)expression];
return [MLExpressionManager expressionAttributedStringWithString:self expression:expression];
}

@end
14 changes: 10 additions & 4 deletions Example/MLLabel/ViewControllers/ListNoNibViewController.m
Expand Up @@ -27,14 +27,21 @@ - (void)viewDidLoad {
[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];
self.title = @"ListNoNib(little higher performance)";
self.title = @"ListNoNib(wait 1.0sec)";

[self.tableView registerClass:[ListNoNibTableViewCell class] forCellReuseIdentifier:[ListNoNibTableViewCell cellReuseIdentifier]];

// MLExpression *exp = [MLExpression expressionWithRegex:@"\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]" plistName:@"Expression" bundleName:@"OriginalExpression"];
MLExpression *exp = [MLExpression expressionWithRegex:@"\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]" plistName:@"Expression" bundleName:@"ClippedExpression"];

self.expressionData = [MLExpressionManager expressionAttributedStringsWithStrings:kCommonListData() expression:exp];
// self.expressionData = [MLExpressionManager expressionAttributedStringsWithStrings:kCommonListData() expression:exp];
//模拟回调处理表情
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[MLExpressionManager expressionAttributedStringsWithStrings:kCommonListData() expression:exp callback:^(NSArray *result) {
self.expressionData = result;
[self.tableView reloadData];
}];
});
}

- (void)didReceiveMemoryWarning {
Expand All @@ -55,10 +62,9 @@ - (NSMutableDictionary *)cellHeights
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 15;
return self.expressionData?15:0; //配合模拟回调处理表情
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

Expand Down
2 changes: 1 addition & 1 deletion MLLabel.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "MLLabel"
s.version = "1.6"
s.version = "1.7"
s.summary = "UILabel with TextKit. support Link and Expression. (iOS 7+)"

s.homepage = 'https://github.com/molon/MLLabel'
Expand Down

0 comments on commit eefb679

Please sign in to comment.