mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-20 00:24:43 +02:00
Improve link detection near timeline touch location
This commit is contained in:
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
@import UIKit;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UITextView(MatrixKit)
|
||||
|
||||
/**
|
||||
Determine if there is a link near a location point in UITextView bounds.
|
||||
|
||||
@param point The point inside the UITextView bounds
|
||||
@return YES to indicate that a link has been detected near the location point.
|
||||
*/
|
||||
- (BOOL)isThereALinkNearPoint:(CGPoint)point;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "UITextView+MatrixKit.h"
|
||||
|
||||
@implementation UITextView(MatrixKit)
|
||||
|
||||
- (BOOL)isThereALinkNearPoint:(CGPoint)point
|
||||
{
|
||||
if (!CGRectContainsPoint(self.bounds, point))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
UITextPosition *textPosition = [self closestPositionToPoint:point];
|
||||
|
||||
if (!textPosition)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
UITextRange *textRange = [self.tokenizer rangeEnclosingPosition:textPosition
|
||||
withGranularity:UITextGranularityCharacter
|
||||
inDirection:UITextLayoutDirectionLeft];
|
||||
|
||||
if (!textRange)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSInteger startIndex = [self offsetFromPosition:self.beginningOfDocument toPosition:textRange.start];
|
||||
|
||||
if (startIndex < 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [self.attributedText attribute:NSLinkAttributeName atIndex:startIndex effectiveRange:NULL] != nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UITextView {
|
||||
private enum Constants {
|
||||
/// Distance threshold at which link can still be considered as "near" from location.
|
||||
static let linkHorizontalDistanceThreshold: CGFloat = 16.0
|
||||
}
|
||||
|
||||
/// Determine if there is a link near a location point in UITextView bounds.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - point: The point inside the UITextView bounds
|
||||
/// - Returns: true to indicate that a link has been detected near the location point.
|
||||
@objc func isThereALinkNearPoint(_ point: CGPoint) -> Bool {
|
||||
guard bounds.contains(point),
|
||||
let textPosition = closestPosition(to: point)
|
||||
else {
|
||||
return false
|
||||
}
|
||||
|
||||
// Depending on cursor position on a character containing both an attachment
|
||||
// and a link (e.g. a mention pill), a positive result can be retrieved either
|
||||
// from textStylingAtPosition or tokenizer's rangeEnclosingPosition.
|
||||
if let attributes = textStyling(at: textPosition, in: .forward),
|
||||
attributes[.link] != nil {
|
||||
// Using textStyling shouldn't provide false positives.
|
||||
return true
|
||||
} else if let textRange = tokenizer.rangeEnclosingPosition(textPosition,
|
||||
with: .character,
|
||||
inDirection: .layout(.left)) {
|
||||
let startIndex = offset(from: beginningOfDocument, to: textRange.start)
|
||||
if attributedText.attribute(.link, at: startIndex, effectiveRange: nil) != nil {
|
||||
// Fix false positives from tokenizer's rangeEnclosingPosition.
|
||||
// These occur if given point is located on the same line as a
|
||||
// trailing character containing a mention pill. Detected link is
|
||||
// rejected if actual distance from attachment trailing to point
|
||||
// is greater than linkHorizontalDistanceThreshold.
|
||||
let glyphIndex = layoutManager.glyphIndexForCharacter(at: startIndex)
|
||||
let attachmentWidth = layoutManager.attachmentSize(forGlyphAt: glyphIndex).width
|
||||
let glyphStartX = layoutManager.location(forGlyphAt: glyphIndex).x
|
||||
let distance = point.x - (glyphStartX + attachmentWidth)
|
||||
|
||||
// TODO: improve using a range perhaps (beware of negative values when no attachment)
|
||||
return distance < Constants.linkHorizontalDistanceThreshold
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user