Subclass NSTextStorage Fails Access Link

I create my own NSTextStorage class to find and map user input and process it inside my application. So I followed a few tutorials, especially objc.io's , and created a subclass and set its layoutManager to be the same from the UITextView created with nib:

 -(void)setCustomTextStorage:(NSTextStorage *)customTextStorage { if (_customTextStorage != customTextStorage) { _customTextStorage = customTextStorage; [_customTextStorage addLayoutManager:self.textView.layoutManager]; } } 

Then override processEditing for the NSTextStorage subclass and add NSLinkAttributeName if necessary.

BTW, an example application is available here , be sure to check the custom-text-storage branch or just read the diff for this problem here

Now, when the user clicks on the actual link, I get an exception that causes the application to crash:

 2014-08-20 23:06:45.223 JSQMessages[63170:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSConcreteTextStorage attribute:atIndex:effectiveRange:]: Range or index out of bounds' *** First throw call stack: ( 0 CoreFoundation 0x00000001025d2495 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x00000001021a999e objc_exception_throw + 43 2 CoreFoundation 0x00000001025d22ad +[NSException raise:format:] + 205 3 UIFoundation 0x000000010558273f -[NSConcreteTextStorage attribute:atIndex:effectiveRange:] + 115 4 UIKit 0x00000001013d401b -[UITextView(LinkInteraction) _interactableItemAtPoint:] + 789 5 UIKit 0x00000001013d59a4 -[UITextView(LinkInteraction) willInteractWithLinkAtPoint:] + 17 6 UIKit 0x000000010108801b -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) gestureRecognizerShouldBegin:] + 305 7 UIKit 0x000000010107fc7b -[UIGestureRecognizer _shouldBegin] + 1026 8 UIKit 0x000000010107cdfd -[UIGestureRecognizer setState:] + 183 9 UIKit 0x0000000100ebcd3f -[UIDelayedAction timerFired:] + 68 10 Foundation 0x0000000101d93e14 __NSFireTimer + 83 11 CoreFoundation 0x0000000102594c34 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 12 CoreFoundation 0x00000001025947b2 __CFRunLoopDoTimer + 962 13 CoreFoundation 0x000000010257d7be __CFRunLoopRun + 1614 14 CoreFoundation 0x000000010257cd83 CFRunLoopRunSpecific + 467 15 GraphicsServices 0x0000000103c2ef04 GSEventRunModal + 161 16 UIKit 0x0000000100d56e33 UIApplicationMain + 1010 17 JSQMessages 0x0000000100014ea3 main + 115 18 libdyld.dylib 0x000000010339f5fd start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException 

Which is strange, because I set a breakpoint there, and the backingStore returns an absolutely valid NSDictionary with attributes.

I will be happy to buy beer for someone who will give me a hand with this crazy problem.

Note. Also playable on iOS 8, so I don't think this is an iOS bug

+5
source share
1 answer

Meets the same problem. The only solution I found now is to create a full stack programmatically instead of using nib:

 self.textStorage = [[CustomTextStorage alloc] init]; NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; [self.textStorage addLayoutManager:layoutManager]; NSTextContainer *textContainer = [[NSTextContainer alloc] init]; [layoutManager addTextContainer:textContainer]; UITextView *textView = [[UITextView alloc] initWithFrame:frame textContainer:textContainer]; textView.delegate = self; 
+2
source

Source: https://habr.com/ru/post/1200788/


All Articles