JSQMessagesViewController custom link

2019-07-26 22:54发布

问题:

I'm using a swift framework and I need to be able to have a # like tag inside of a message text string. If a user sends a message containing a code prefixed with a #, for example: #t3Us9K that single "word" needs to be a link that all users can press. please tell me if this is possible and if so how to do it.

回答1:

I had been working on your question and this are my results,

First of all you need to modify JSQMessagesCellTextView in the library and add a method to help you to detect custom links, like #test, If you want you can clone my fork with this feature added and this is how it looks, the animation issue is because my gif converter

EDITED

https://github.com/rmelian2014/JSQMessagesViewController/tree/contributing

- (void)detectCustomLinks
{
    NSMutableArray<NSTextCheckingResult*>  *textCheckingResults = [NSMutableArray<NSTextCheckingResult*> array];
    for (NSRegularExpression *exp in [self.regularExpressionsDelegate getRegularExpressions]) {
        NSArray<NSTextCheckingResult*> * matches = [exp matchesInString:self.text options:NSMatchingWithoutAnchoringBounds range:NSMakeRange(0, self.text.length)];
        [textCheckingResults addObjectsFromArray:matches];
    }

    NSMutableAttributedString * str2 = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];

    [str2 removeAttribute:NSLinkAttributeName range:NSMakeRange(0, str2.string.length)];
    for (NSTextCheckingResult * match in textCheckingResults) {
        [str2 addAttribute: NSLinkAttributeName value:[str2 attributedSubstringFromRange:match.range].string range:match.range];
    }

    self.attributedText = str2;
}

I had added a delegate to provide regular expressions to check with

@protocol RegularExpressionDelegate <NSObject>

-(NSArray<NSRegularExpression*>*)getRegularExpressions;

@end

/**
 *  `JSQMessagesCellTextView` is a subclass of `UITextView` that is used to display text
 *  in a `JSQMessagesCollectionViewCell`.
 */
@interface JSQMessagesCellTextView : UITextView

@property (weak) id<RegularExpressionDelegate> regularExpressionsDelegate;

@end

and then you need to put your viewController as UITextViewDelegate and finally in your cellForRowAtIndexPath you need to put something like this

cell.textView.regularExpressionsDelegate = self;
cell.textView.delegate = self;

this will put your viewController as regularExpressionsDelegate and then you need to implement this method, returning the regular expressions that you want be detected as customs links

- (NSArray<NSRegularExpression*>*)getRegularExpressions
{
    return [NSArray arrayWithObject:[NSRegularExpression regularExpressionWithPattern:@"#([a-zA-Z0-9])+" options:0 error:NULL]];
} 

also you need to implement this

//UITextViewDelegateMethod
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
    //URL param will provide the link that was touched ej:#test
    return YES;
}

I Hope this helps you, Regards