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
|