-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accessibility on Cards. #86
Accessibility on Cards. #86
Conversation
accessibilityLabel = [ | ||
title, | ||
headline, | ||
subtitle, | ||
descriptionTitle | ||
].compactMap { $0 }.joined(separator: " ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe in the future we should ask product for a good definition on how this accessibility label should be composed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following , they read all the items on their cards like we do in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great. Thanks for doing this!
I am not sure about the proposed implementation, I think that it is not the best voice over experience for elements like Card o List. With the proposed implementation the voice over will handle a card like a unique element but what will happens with media cards or cards with fragments? I was researching about how voice over works in other apps. For example the feed of the Apple Store app is built with a mix of cards and lists, the elements of the feed have different interactions with voice over. For example, they have a card which interacts like a single element (for me this card is very similar to our HighlitedCard but without buttons) They also have rows with texts and a buttons. This element interacts with voice in two steps: the texts and the button They also have media cards: a video and texts, this elements interacts with the voice over for each subviewI think, we should try to replicate some of the above behaviours but always allowing to be customized. |
But the proposed implementation is breaking a card with fragment but without buttons because the fragment view will be invisible for the voice over.
I think we can get something similar to what Apple does... My point is, we evaluate a set of cards (only texts, buttons, fragments, media, etc) and try to define a behaviour for them but keeping the possibility to be customised by a user of it component. Maybe as Guille says, we should move this topic with design core and other platforms (web and android). |
UpdateUsed UIAccessibilityElement on cards to improve accessibility. |
@@ -57,6 +58,18 @@ public class MediaCard: UIView { | |||
} | |||
} | |||
|
|||
override public var accessibilityElements: [Any]? { | |||
get { | |||
accessibilityElement.accessibilityFrameInContainerSpace = bounds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would love to have a commet describing why are we doing this here.
override var accessibilityTraits: UIAccessibilityTraits { | ||
get { | ||
accessibilityElement.accessibilityTraits | ||
} | ||
set { | ||
accessibilityElement.accessibilityTraits = newValue | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this override?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The card isn't accessible, because the accessibilityElement is what we are making accessible. So, if we want to update the trait of the card, usually as button, we need to set that trait to the accessibilityElement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, but why do we need this override? I mean, in my tests adding the traits to the custom accessibility element is good enough. Did you find some issue without overriding?
Also, if the accessibility element has a trait of type button, which action is fire after tap?
My fault, I was thinking that the trait was set to cardAccessibilityElement but it is not.
accessibilityElement.accessibilityLabel = [ | ||
configuration.headline, | ||
configuration.title, | ||
configuration.subtitle, | ||
configuration.descriptionTitle | ||
].compactMap { $0 }.joined(separator: " ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if we should use the headline text or the accessibilityLabel... My concern is that the accessibilityLabel of headline can be different from the text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 True, the label could be different, I'll update it.
@@ -63,6 +63,7 @@ public class DataCard: UIView { | |||
static let largeIconSize = CGFloat(24) | |||
} | |||
|
|||
private lazy var accessibilityElement = UIAccessibilityElement(accessibilityContainer: self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would named it like: cardAccessibilityElement
@@ -31,6 +31,7 @@ public class HighlightedCard: UIView { | |||
case secondary | |||
} | |||
|
|||
private lazy var accessibilityElement = UIAccessibilityElement(accessibilityContainer: self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same than above
accessibilityElement.accessibilityFrameInContainerSpace = bounds | ||
return [ | ||
accessibilityElement, | ||
fragmentView as Any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this cast?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid the Xcode warning about your implicitly casting from N to Any.
Good work improving the accessibility of cards! But I have some suggestions: I am missing documentation about how the user can add support to voice over for the fragment view. I am thinking in documentation about how the user can make the fragment view as unique accessibility element or as multiple accessibility elements. If I am not wrong, for the RichMedia card we are not adding the media as part of the accessibility element. I am thinking in a card with a video. |
…EADME of cards component.
Co-authored-by: Julian <julian.alonsocarballo@telefonica.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## [9.0.1](v9.0.0...v9.0.1) (2021-02-24) ### Bug Fixes * **Accessibility:** improve Accessibility on Cards. Update Cards docs ([#86](#86)) ([3bbe36b](3bbe36b))
🎉 This PR is included in version 9.0.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Hi!
Set card accessibilityElement to true when it has no buttons, if it has buttons isn't set because if we set the card as an unique accesible element for voiceover the buttons are not accesibles, like if them doesn't exists.
If a user uses the card as a button he must set the traits.