1

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.

Jacolack
  • 1,365
  • 2
  • 11
  • 25
  • what does "Im using a swift Framework" refer to. is JSQmessages the swift framework or a swift framework that lets you detect `#` – Dan Leonard Jul 01 '16 at 16:06
  • The answer to your first question is yes this is possible but how may not fit on this form. – Dan Leonard Jul 01 '16 at 16:07
  • @Daniel the framework I was referring to is JSQMessagesViewController. And what do you mean how many not fit on this form? – Jacolack Jul 02 '16 at 07:47
  • Your question is how to implement an entire solution not a specific question on a single problem. I am not trying to step on your question but it's a little to general and broad, it would be nearly impossible to answer it without your entire code base to see what you are trying to do and how things are set up. If you have a more specific question that is where stack overflow really shines. You don't have to listen to my suggestions but since this is all volunteer I don't anyone will take a stab at it. That is all I am saying. – Dan Leonard Jul 02 '16 at 18:30

1 Answers1

2

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

enter image description here

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

Reinier Melian
  • 20,519
  • 3
  • 38
  • 55