diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.m index ed9f5271..ad9f5e3d 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertExpandableView.m @@ -61,6 +61,18 @@ } } +- (void)amendAccesibilityLabel { + NSString *amendment = [MVMCoreUIUtility hardcodedStringWithKey:@"top_alert_notification"]; + NSString *accessibilityLabel = self.buttonView.label.accessibilityLabel; + if (!accessibilityLabel) { + // The accessibility label is nil when in non-voice over mode. Therefore assign the label text for the voice over is turned on mid-session (i.e. testers 🤦). + accessibilityLabel = self.buttonView.label.text; + } + if (accessibilityLabel && ![accessibilityLabel hasPrefix:amendment]) { + self.buttonView.label.accessibilityLabel = [NSString stringWithFormat:@"%@ - %@", amendment, accessibilityLabel]; + } +} + #pragma mark - Setup View - (void)updateView:(CGFloat)size { @@ -74,6 +86,7 @@ self.translatesAutoresizingMaskIntoConstraints = NO; self.clipsToBounds = YES; self.expanded = NO; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(accessibilityFocusChanged:) name:UIAccessibilityElementFocusedNotification object:nil]; } return self; } @@ -167,6 +180,8 @@ [self insertSubview:topAlertWithButton belowSubview:self.shortView]; self.buttonView = topAlertWithButton; + [self amendAccesibilityLabel]; + self.topConstraint = [NSLayoutConstraint constraintWithItem:topAlertWithButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.shortView attribute:NSLayoutAttributeBottom multiplier:1 constant:0]; [NSLayoutConstraint constraintPinSubview:topAlertWithButton pinTop:NO topConstant:0 pinBottom:YES bottomConstant:0 pinLeft:YES leftConstant:0 pinRight:YES rightConstant:0]; } @@ -207,6 +222,7 @@ [MVMCoreDispatchUtility performBlockOnMainThread:^{ [self setTopMessage:topMessage]; [self.buttonView setupWithMessage:message subMessage:subMessage color:contentColor actionMap:actionMap additionalData:additionalData]; + [self amendAccesibilityLabel]; }]; } @@ -214,6 +230,7 @@ [MVMCoreDispatchUtility performBlockOnMainThread:^{ [self setTopMessage:topMessage]; [self.buttonView setupWithMessage:message subMessage:subMessage color:contentColor buttonTitle:buttonTitle userActionHandler:userActionHandler]; + [self amendAccesibilityLabel]; }]; } @@ -304,7 +321,6 @@ //accessibility - added to make only top alert label and close button accessible. Posted notification when top alert is displayed weakSelf.accessibilityElements = @[weakSelf.buttonView]; weakSelf.shortView.isAccessibilityElement = NO; - weakSelf.buttonView.label.accessibilityLabel = [NSString stringWithFormat:@"%@ - %@", [MVMCoreUIUtility hardcodedStringWithKey:@"top_alert_notification"],weakSelf.buttonView.label.accessibilityLabel]; void(^completion)(void) = ^(void) { UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, weakSelf.buttonView.label); @@ -346,7 +362,7 @@ } dispatch_time_t dispatchTime = dispatch_time(DISPATCH_TIME_NOW, dismissTime * NSEC_PER_SEC); dispatch_after(dispatchTime, dispatch_get_main_queue(), ^(void){ - if (weakSelf && weakSelf.expanded && weakSelf.collapseAutomaticallyAfterExpanded) { + if (weakSelf && weakSelf.expanded && weakSelf.collapseAutomaticallyAfterExpanded && ![self containsAccessiblityFocus]) { [weakSelf collapse]; } }); @@ -390,4 +406,21 @@ } } +- (BOOL)containsAccessiblityFocus { + if (!UIAccessibilityIsVoiceOverRunning()) { + return NO; + } + id focusedElement = UIAccessibilityFocusedElement(UIAccessibilityNotificationVoiceOverIdentifier); + if (![focusedElement isKindOfClass:[UIView class]]) { + return NO; + } + return [(UIView *)focusedElement isDescendantOfView:self]; +} + +- (void)accessibilityFocusChanged:(NSNotification *)notification { + if (![self containsAccessiblityFocus]) { + [self collapse]; + } +} + @end