Skip to content

Commit

Permalink
[Snackbar] Adds elementToFocusOnDismiss to MDCSnackbar (#9148)
Browse files Browse the repository at this point in the history
As part of maintaining same functionality across our iterations of the Snackbar, this code was ported from the older iteration to allow users to choose focus on different views after Snackbar is dismissed.
  • Loading branch information
yarneo committed Dec 6, 2019
1 parent 4e41462 commit a14b9c6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
9 changes: 9 additions & 0 deletions components/Snackbar/src/MDCSnackbarMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@ extern NSString *__nonnull const MDCSnackbarMessageBoldAttributeName;
*/
@property(nonatomic) BOOL focusOnShow;

/**
Element to focus on snackbar message dismiss. Focuses the first element on screen
after dismiss by default. The focus will change to the element only if the focus is on the snackbar
message.
Defaults to nil.
*/
@property(nonatomic, weak, nullable) UIView *elementToFocusOnDismiss;

/**
A block that is invoked when the corresponding @c MDCSnackbarMessageView of the @c
MDCSnackbarMessage instance will be presented. Use this to customize @c MDCSnackbarMessageView
Expand Down
1 change: 1 addition & 0 deletions components/Snackbar/src/MDCSnackbarMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ - (instancetype)copyWithZone:(__unused NSZone *)zone {
#pragma clang diagnostic pop
copy.enableRippleBehavior = self.enableRippleBehavior;
copy.focusOnShow = self.focusOnShow;
copy.elementToFocusOnDismiss = self.elementToFocusOnDismiss;

// Unfortunately there's not really a concept of 'copying' a block (in the same way you would copy
// a string, for example). A block's pointer is immutable once it is created and copied to the
Expand Down
21 changes: 21 additions & 0 deletions components/Snackbar/src/MDCSnackbarMessageView.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@
alpha:(a)];
}

/** Test whether any of the accessibility elements of a view is focused */
static BOOL UIViewHasFocusedAccessibilityElement(UIView *view) {
for (NSInteger i = 0; i < [view accessibilityElementCount]; i++) {
id accessibilityElement = [view accessibilityElementAtIndex:i];
if ([accessibilityElement accessibilityElementIsFocused]) {
return YES;
}
}
return NO;
};

/**
The thickness of the Snackbar border.
*/
Expand Down Expand Up @@ -421,6 +432,16 @@ - (void)dismissWithAction:(MDCSnackbarMessageAction *)action userInitiated:(BOOL
if (self.dismissalHandler) {
self.dismissalHandler(userInitiated, action);

// Change focus only if the focus is on this view.
if (self.message.elementToFocusOnDismiss) {
BOOL hasVoiceOverFocus =
UIAccessibilityIsVoiceOverRunning() && UIViewHasFocusedAccessibilityElement(self);
if (hasVoiceOverFocus) {
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification,
self.message.elementToFocusOnDismiss);
}
}

// In case our dismissal handler has a reference to us, release the block.
self.dismissalHandler = nil;
}
Expand Down

0 comments on commit a14b9c6

Please sign in to comment.