Skip to content

Commit 1e03c49

Browse files
Nobodymaterial-automation
Nobody
authored andcommitted
Add a new property shouldCenterActivationPoint to NIViewAccessibilityElement.
This property ensures multiline NIViewAccessibilityElements have unique touch points when merging multiline links into a single NIViewAccessibilityElement. When the first link contains either the first or the last word in the sentence and the second link spills between more than one line, the NIViewAccessibilityElement frames have the same top left point, which is used as the touch point. This causes an issue where NIAttributedLabel can't determine which accessibilityElement a touchPoint originated from, meaning that one of the two links can't register events. We solve this by using the center point of the frame, which is ensured to be unique (only for links in the same text) as multiline element frames would have unique y-coordinates. PiperOrigin-RevId: 544181302
1 parent 390b1ce commit 1e03c49

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

src/attributedlabel/src/NIAttributedLabel.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,17 @@ @interface NIViewAccessibilityElement ()
173173
// performed.
174174
@property (nonatomic) BOOL isContainerDataValid;
175175

176+
// This property ensures multiline NIViewAccessibilityElements have unique
177+
// touch points when merging multiline links into a single NIViewAccessibilityElement.
178+
// When the first link contains either the first or the last word in the sentence and the second
179+
// link spills between more than one line, the NIViewAccessibilityElement
180+
// frames have the same top left point, which is used as the touch point. This causes an
181+
// issue where NIAttributedLabel can't determine which accessibilityElement a touchPoint
182+
// originated from, meaning that one of the two links can't register events.
183+
// We solve this by using the center point of the frame, which is ensured to be unique
184+
// (only for links in the same text) as multiline element frames would have unique y-coordinates.
185+
@property (nonatomic) BOOL shouldCenterActivationPoint;
186+
176187
@end
177188

178189
@implementation NIViewAccessibilityElement
@@ -204,6 +215,7 @@ - (instancetype)initWithAccessibilityContainer:(id)container {
204215
frameInContainer:CGRectZero
205216
pointsInContainer:nil]) {
206217
self.isContainerDataValid = NO;
218+
self.shouldCenterActivationPoint = NO;
207219
}
208220
return self;
209221
}
@@ -273,6 +285,13 @@ - (CGPoint)accessibilityActivationPoint {
273285
point = [accessibilityContainerView.window convertPoint:point toWindow:nil];
274286
return point;
275287
}
288+
if (_shouldCenterActivationPoint) {
289+
// Since links cannot overlap, using the center of the start and end points
290+
// of the explicit link location ensures unique touch points from events.
291+
CGPoint startPoint = [[_pointsInContainer firstObject] CGPointValue];
292+
CGPoint endPoint = [[_pointsInContainer lastObject] CGPointValue];
293+
return CGPointMake((startPoint.x+endPoint.x)/2.0, (startPoint.y+endPoint.y)/2.0);
294+
}
276295
return super.accessibilityActivationPoint;
277296
}
278297

@@ -1911,6 +1930,7 @@ - (NSArray *)accessibleElements {
19111930
NIViewAccessibilityElement *element = [[NIViewAccessibilityElement alloc]
19121931
initWithAccessibilityContainer:self
19131932
frameInContainer:rectValue.CGRectValue];
1933+
element.shouldCenterActivationPoint = _shouldMergeMultilineLinks;
19141934
[self updateAccessibilityLabelOnElement:element withAccessibilityLabel:label];
19151935

19161936
// Set the frame to fallback on if |element|'s accessibility container is changed

0 commit comments

Comments
 (0)