From 72be8a5c4f7655b043dc3110fb2ef84fd40dd805 Mon Sep 17 00:00:00 2001 From: Alex Odawa Date: Thu, 19 Sep 2024 20:24:38 +0200 Subject: [PATCH] take the accessibilityActivation point into consideration when tapping elements --- Sources/KIF/Classes/KIFUITestActor.m | 8 +++ TestHost/AccessibilityViewController.m | 59 ++++++++++++------- TestHost/Base.lproj/MainStoryboard.storyboard | 14 ++--- ...cessibilityActivationTests_ViewTestActor.m | 14 +++++ 4 files changed, 68 insertions(+), 27 deletions(-) diff --git a/Sources/KIF/Classes/KIFUITestActor.m b/Sources/KIF/Classes/KIFUITestActor.m index e28fae7e..cbabd652 100644 --- a/Sources/KIF/Classes/KIFUITestActor.m +++ b/Sources/KIF/Classes/KIFUITestActor.m @@ -1673,6 +1673,14 @@ - (CGRect) elementFrameForElement:(UIAccessibilityElement *)element andView:(UIV - (CGPoint) tappablePointInElement:(UIAccessibilityElement *)element andView:(UIView *)view { + // AccessibilityActivationPoint indicates where on the element assistive technologies should issue a tap event to activate the element. + // In the case where the property has not been explicitly set. The default value is the midpoint of the accessibility frame. + UIView *hitView = [view.window hitTest:element.accessibilityActivationPoint withEvent:nil]; + if ([view isTappableWithHitTestResultView:hitView]) { + return [view.window convertPoint:element.accessibilityActivationPoint toView:view]; + } + + // If the element's AccessibilityActivationPoint is not tappable, attempt to find a suitable tappable point within the element's frame. CGRect elementFrame = [self elementFrameForElement:element andView:view]; CGPoint tappablePoint = [view tappablePointInRect:elementFrame]; diff --git a/TestHost/AccessibilityViewController.m b/TestHost/AccessibilityViewController.m index 068c125f..6290a3cb 100644 --- a/TestHost/AccessibilityViewController.m +++ b/TestHost/AccessibilityViewController.m @@ -11,10 +11,10 @@ @interface AccessibilityViewController_AccessibilityView : UIView @property (nonatomic, assign) BOOL activationReturnValue; @property (nonatomic, assign) int activationCount; -@property (nonatomic, strong) UILabel *label; +@property (nonatomic, strong) UILabel *topLabel; +@property (nonatomic, strong) UILabel *swtichLabel; @property (nonatomic, strong) UISwitch *activationSwitch; - @end @@ -24,16 +24,16 @@ - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; self.isAccessibilityElement = YES; self.accessibilityLabel = @"AccessibilityView"; - - + self.activationReturnValue = YES; - - self.label = [[UILabel alloc] initWithFrame: CGRectZero]; - [self addSubview:self.label]; - - self.backgroundColor = [UIColor systemTealColor]; - self.label.text = @"Returns YES"; + self.topLabel = [[UILabel alloc] initWithFrame: CGRectZero]; + self.topLabel.text = @"Awaiting activation or tap"; + [self addSubview:self.topLabel]; + + self.swtichLabel = [[UILabel alloc] initWithFrame: CGRectZero]; + self.swtichLabel.text = @"Returns YES"; + [self addSubview:self.swtichLabel]; self.activationSwitch = [[UISwitch alloc] initWithFrame: CGRectZero]; [self addSubview: self.activationSwitch]; @@ -50,35 +50,54 @@ - (void)toggleReturnValue { if (self.activationReturnValue == YES) { self.backgroundColor = [UIColor systemTealColor]; - self.label.text = @"Returns YES"; + self.swtichLabel.text = @"Returns YES"; } else { self.backgroundColor = [UIColor systemTealColor]; - self.label.text = @"Returns NO"; + self.swtichLabel.text = @"Returns NO"; } [self setNeedsLayout]; } -(void)layoutSubviews { [super layoutSubviews]; - [self.label sizeToFit]; - self.label.frame = CGRectMake((self.frame.size.width - self.label.frame.size.width) / 2, - (self.frame.size.height - self.label.frame.size.height) / 2, - self.label.frame.size.width, - self.label.frame.size.height); + [self.topLabel sizeToFit]; + self.topLabel.frame = CGRectMake(20, + 20, + self.topLabel.frame.size.width, + self.topLabel.frame.size.height); + + [self.swtichLabel sizeToFit]; + self.swtichLabel.frame = CGRectMake(20, + CGRectGetMaxY(self.topLabel.frame) + 40, + self.swtichLabel.frame.size.width, + self.swtichLabel.frame.size.height); [self.activationSwitch sizeToFit]; - self.activationSwitch.frame = CGRectMake((self.frame.size.width - self.activationSwitch.frame.size.width) / 2, - CGRectGetMaxY(self.label.frame) + 10 , + self.activationSwitch.frame = CGRectMake(20, + CGRectGetMaxY(self.swtichLabel.frame) + 10 , self.activationSwitch.frame.size.width, self.activationSwitch.frame.size.width); + +} + +- (NSString *)accessibilityValue { + return self.topLabel.text; } - (BOOL)accessibilityActivate { self.activationCount += 1; - self.accessibilityValue = [NSString stringWithFormat:@"Activated: %i", self.activationCount]; + self.topLabel.text = [NSString stringWithFormat:@"Activated: %i", self.activationCount]; + [self setNeedsLayout]; return self.activationReturnValue; } + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + CGPoint location = [[touches anyObject] locationInView: self]; + self.topLabel.text = [NSString stringWithFormat:@"Tapped - x:%.04f, y:%.04f", location.x, location.y]; + [self setNeedsLayout]; +} + @end @interface AccessibilityViewController : UIViewController diff --git a/TestHost/Base.lproj/MainStoryboard.storyboard b/TestHost/Base.lproj/MainStoryboard.storyboard index 568e3418..439e9f23 100644 --- a/TestHost/Base.lproj/MainStoryboard.storyboard +++ b/TestHost/Base.lproj/MainStoryboard.storyboard @@ -2170,13 +2170,13 @@ Line Break - + - + - - - + + + @@ -2184,12 +2184,12 @@ Line Break - + - + diff --git a/Tests/AccessibilityActivationTests_ViewTestActor.m b/Tests/AccessibilityActivationTests_ViewTestActor.m index 131f3541..da867445 100644 --- a/Tests/AccessibilityActivationTests_ViewTestActor.m +++ b/Tests/AccessibilityActivationTests_ViewTestActor.m @@ -6,6 +6,7 @@ // #import +#import @interface AccessibilityActivateTests_ViewTestActor : KIFTestCase @end @@ -33,4 +34,17 @@ - (void)testAccessibilityActivate [[viewTester usingValue:@"Activated: 2"] waitForView]; } +- (void)testAccessibilityActiationPoint +{ + UIView *view = [[viewTester usingValue: @"Awaiting activation or tap"] waitForView]; + [view setAccessibilityActivationPoint: [view.window convertPoint:CGPointMake(25.0, 50.0) fromView:view]]; + + [[viewTester usingLabel: @"AccessibilityView"] tap]; + [[viewTester usingValue:@"Tapped - x:25.0000, y:50.0000"] waitForView]; + + [view setAccessibilityActivationPoint: [view.window convertPoint:CGPointMake(50.0, 25.0) fromView:view]]; + [[viewTester usingLabel: @"AccessibilityView"] tap]; + [[viewTester usingValue:@"Tapped - x:50.0000, y:25.0000"] waitForView]; +} + @end