ibireme / YYKit

A collection of iOS components.
MIT License
13.99k stars 3.69k forks source link

微博话题转成单井号 #218

Closed zww965539071 closed 8 years ago

zww965539071 commented 8 years ago

1.我在WBStatusHelper.m里将rexTopic方法中的正则换为了@"#([\u4e00-\u9fa5\w~`!$%^&*()_-+=:;'\",.<>?/{}[]|]+)"
2.然后在WBStatusComposeTextParser.m里将话题图片方法禁掉:
dispatch_once(&onceToken, ^{ // topicExts = @[ @"[电影]#", @"[图书]#", @"[音乐]#", @"[地点]#", @"[股票]#" ]; // topicExtImages = @[ // [WBStatusHelper imageNamed:@"timeline_card_small_movie"], // [WBStatusHelper imageNamed:@"timeline_card_small_book"], // [WBStatusHelper imageNamed:@"timeline_card_small_music"], // [WBStatusHelper imageNamed:@"timeline_card_small_location"], // [WBStatusHelper imageNamed:@"timeline_card_small_stock"] // ]; topicExts = @[ @" #"]; topicExtImages = @[ [WBStatusHelper imageNamed:@"timeline_card_small_movie"], ]; });

禁掉之后我的写法是: NSArray<NSTextCheckingResult > topicResults = [[WBStatusHelper regexTopic] matchesInString:text.string options:kNilOptions range:text.rangeOfAll]; NSUInteger clipLength = 0; for (NSTextCheckingResult *topic in topicResults) {

        if (topic.range.location == NSNotFound && topic.range.length <= 1) continue;
        NSRange range = topic.range;
        range.location -= clipLength;

        __block BOOL containsBindingRange = NO;
        [text enumerateAttribute:YYTextBindingAttributeName inRange:range options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
            if (value) {
                containsBindingRange = YES;
                *stop = YES;
            }
        }];
        if (containsBindingRange) continue;//为yes则不执行下面方法,当遍历到最后一个#号时则跳出.为no则执行

        BOOL hasExt = NO;
        NSString *subText = [text.string substringWithRange:range];

        NSMutableAttributedString *replace = [[NSMutableAttributedString alloc] initWithString:[subText substringWithRange:NSMakeRange(0, subText.length)]];

                replace.font = _font;
                replace.color = _highlightTextColor;

                // original text, used for text copy
                YYTextBackedString *backed = [YYTextBackedString stringWithString:subText];
                [replace setTextBackedString:backed range:NSMakeRange(0, replace.length)];

                [text replaceCharactersInRange:range withAttributedString:replace];
                [text setTextBinding:[YYTextBinding bindingWithDeleteConfirm:YES] range:NSMakeRange(range.location, replace.length)];
                [text setColor:_highlightTextColor range:NSMakeRange(range.location, replace.length)];
                if (selectedRange) {
                    *selectedRange = [self _replaceTextInRange:range withLength:replace.length selectedRange:*selectedRange];
                }

                clipLength += range.length - replace.length;
                hasExt = YES;
                break;
    }

3.以上操作完成后,我在yyTextView外部提供的方法:- (void)replaceRange:(YYTextRange )range withText:(NSString )text ,将我要输入的话题字符串变成形式@"#Hello",然后调用该方法.

4.所以操作完成后,我可以实现在文本框中输入单井号的话题,效果和yyKit提供的微博效果一样,问题是将若干个话题一起copy,plaste后,plaste的内容只有plaste内容的第一个话题会变蓝色,只有此时不断输入文字,之后的话题才会一个一个的变为蓝色。(比如文本框中已经存在若干话题@"#nihao#hello#welcome",此时copy这三个话题,plaste后的效果是之前的被copy三话题显示正常为蓝色,而后添加的#nihao为蓝色,#hello和#welcome为黑色,此时若输入一个字符,#hello变蓝色,再输入字符,#welcome变蓝色,以此类推) 5.解决上述的问题,我在yyTextView.m方法- (void)paste:(id)sender 中的末尾代码段 NSString *string = p.string; if (string.length > 0) { [self _saveToUndoStack]; [self _resetRedoStack]; [self replaceRange:_selectedTextRange withText:string];//system [self replaceRange:_selectedTextRange withText:@" "];//newAdd(有几个话题就重复该法几次) [self replaceRange:_selectedTextRange withText:@" "];//newAdd ......... } } 可以解决copy后不全变蓝色的问题,但效率不高,若是有100个话题,那我copy后,要走100次replaceRange方法,求大神指点,因为我看到yyKit提供的微博demo,copy起来很顺畅

ibireme commented 8 years ago

那个是在 YYTextView 上添加了个自定义的 textParser 实现的,不用修改内部代码。

zww965539071 commented 8 years ago

那如何在textParser中实现单井号话题的实现,无论是话题还是拷贝话题再粘贴,效果都和demon中的效果一样

ibireme commented 8 years ago

在 textParser 里面用正则也好,scanner 也行,匹配一下警号范围,添加一下属性就行了。具体可以参考 Demo。

wealon commented 6 years ago

确实很好用 匹配完添加一个属性就好了