mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			130 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			130 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Objective-C
		
	
| //
 | |
| //  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
 | |
| //
 | |
| 
 | |
| #import "OWSMessageTextView.h"
 | |
| #import <SessionUtilitiesKit/UIView+OWS.h>
 | |
| 
 | |
| NS_ASSUME_NONNULL_BEGIN
 | |
| 
 | |
| @interface OWSMessageTextView ()
 | |
| 
 | |
| @property (nonatomic, nullable) NSValue *cachedSize;
 | |
| 
 | |
| @end
 | |
| 
 | |
| #pragma mark -
 | |
| 
 | |
| @implementation OWSMessageTextView
 | |
| 
 | |
| // Our message text views are never used for editing;
 | |
| // suppress their ability to become first responder
 | |
| // so that tapping on them doesn't hide keyboard.
 | |
| - (BOOL)canBecomeFirstResponder
 | |
| {
 | |
|     return NO;
 | |
| }
 | |
| 
 | |
| // Ignore interactions with the text view _except_ taps on links.
 | |
| //
 | |
| // We want to disable "partial" selection of text in the message
 | |
| // and we want to enable "tap to resend" by tapping on a message.
 | |
| - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *_Nullable)event
 | |
| {
 | |
|     if (self.shouldIgnoreEvents) {
 | |
|         // We ignore all events for failed messages so that users
 | |
|         // can tap-to-resend even "all link" messages.
 | |
|         return NO;
 | |
|     }
 | |
| 
 | |
|     // Find the nearest text position to the event.
 | |
|     UITextPosition *_Nullable position = [self closestPositionToPoint:point];
 | |
|     if (!position) {
 | |
|         return NO;
 | |
|     }
 | |
|     // Find the range of the character in the text which contains the event.
 | |
|     //
 | |
|     // Try every layout direction (this might not be necessary).
 | |
|     UITextRange *_Nullable range = nil;
 | |
|     for (NSNumber *textLayoutDirection in @[
 | |
|              @(UITextLayoutDirectionLeft),
 | |
|              @(UITextLayoutDirectionRight),
 | |
|              @(UITextLayoutDirectionUp),
 | |
|              @(UITextLayoutDirectionDown),
 | |
|          ]) {
 | |
|         range = [self.tokenizer rangeEnclosingPosition:position
 | |
|                                        withGranularity:UITextGranularityCharacter
 | |
|                                            inDirection:(UITextDirection)textLayoutDirection.intValue];
 | |
|         if (range) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
|     if (!range) {
 | |
|         return NO;
 | |
|     }
 | |
|     // Ignore the event unless it occurred inside a link.
 | |
|     NSInteger startIndex = [self offsetFromPosition:self.beginningOfDocument toPosition:range.start];
 | |
|     BOOL result =
 | |
|         [self.attributedText attribute:NSLinkAttributeName atIndex:(NSUInteger)startIndex effectiveRange:nil] != nil;
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| - (void)setText:(nullable NSString *)text
 | |
| {
 | |
|     if ([NSObject isNullableObject:text equalTo:self.text]) {
 | |
|         return;
 | |
|     }
 | |
|     [super setText:text];
 | |
|     self.cachedSize = nil;
 | |
| }
 | |
| 
 | |
| - (void)setAttributedText:(nullable NSAttributedString *)attributedText
 | |
| {
 | |
|     if ([NSObject isNullableObject:attributedText equalTo:self.attributedText]) {
 | |
|         return;
 | |
|     }
 | |
|     [super setAttributedText:attributedText];
 | |
|     self.cachedSize = nil;
 | |
| }
 | |
| 
 | |
| - (void)setTextColor:(nullable UIColor *)textColor
 | |
| {
 | |
|     if ([NSObject isNullableObject:textColor equalTo:self.textColor]) {
 | |
|         return;
 | |
|     }
 | |
|     [super setTextColor:textColor];
 | |
|     // No need to clear cached size here.
 | |
| }
 | |
| 
 | |
| - (void)setFont:(nullable UIFont *)font
 | |
| {
 | |
|     if ([NSObject isNullableObject:font equalTo:self.font]) {
 | |
|         return;
 | |
|     }
 | |
|     [super setFont:font];
 | |
|     self.cachedSize = nil;
 | |
| }
 | |
| 
 | |
| - (void)setLinkTextAttributes:(nullable NSDictionary<NSString *, id> *)linkTextAttributes
 | |
| {
 | |
|     if ([NSObject isNullableObject:linkTextAttributes equalTo:self.linkTextAttributes]) {
 | |
|         return;
 | |
|     }
 | |
|     [super setLinkTextAttributes:linkTextAttributes];
 | |
|     self.cachedSize = nil;
 | |
| }
 | |
| 
 | |
| - (CGSize)sizeThatFits:(CGSize)size
 | |
| {
 | |
|     if (self.cachedSize) {
 | |
|         return self.cachedSize.CGSizeValue;
 | |
|     }
 | |
|     CGSize result = [super sizeThatFits:size];
 | |
|     self.cachedSize = [NSValue valueWithCGSize:result];
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| @end
 | |
| 
 | |
| NS_ASSUME_NONNULL_END
 |