-
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
IOS-10448 [Mistica] RowList A11y update #399
Changes from all commits
8640aed
166b98d
9773411
e94239c
a8c79ea
e6703fa
89cd6bb
ed72b55
e683233
9f3dabe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,22 +8,32 @@ | |
|
||
import UIKit | ||
|
||
protocol ListCellContentViewDelegate: AnyObject { | ||
func accessibilityChanged() | ||
} | ||
|
||
class CellCenterSectionView: UIStackView { | ||
var headlineView: UIView? { | ||
var accessibilityActivationAction: (() -> Void)? | ||
|
||
var headlineView: AccessibleTextualView? { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Due to it's possible to use any UIView, used a protocol that exposes an accessible text |
||
didSet { | ||
oldValue?.removeFromSuperview() | ||
|
||
if let view = headlineView { | ||
insertArrangedSubview(view, at: 0) | ||
updateSpacing() | ||
} | ||
|
||
listCellContentViewDelegate?.accessibilityChanged() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Notify delegate that accessibility has changed |
||
} | ||
} | ||
|
||
lazy var titleLabel = IntrinsictHeightLabel() | ||
lazy var subtitleLabel = IntrinsictHeightLabel() | ||
lazy var detailLabel = IntrinsictHeightLabel() | ||
|
||
weak var listCellContentViewDelegate: ListCellContentViewDelegate? | ||
|
||
var titleTextColor: UIColor = .textPrimary { | ||
didSet { | ||
titleLabel.textColor = titleTextColor | ||
|
@@ -70,6 +80,15 @@ class CellCenterSectionView: UIStackView { | |
} | ||
} | ||
|
||
override public func accessibilityActivate() -> Bool { | ||
guard let accessibilityActivationAction else { | ||
return false | ||
} | ||
|
||
accessibilityActivationAction() | ||
return true | ||
} | ||
Comment on lines
+83
to
+90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Execute custom accessibility action on double tap if it's defined. This case only occurs in cells with accessibility of type |
||
|
||
func didSetTextToSubtitleLabel() { | ||
if !hasSubtitleText { | ||
subtitleLabel.removeFromSuperview() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,11 +10,51 @@ import UIKit | |
|
||
protocol ListCellContentTableViewDelegate { | ||
func cellStyleChanged() | ||
func accessibilityChanged() | ||
} | ||
|
||
// MARK: ListCellContentView | ||
|
||
open class ListCellContentView: UIView { | ||
// MARK: Accessibility properties | ||
|
||
var accessibilityType: AccessibilityListCellType = .default { | ||
didSet { | ||
if case .doubleInteraction(let accessibilityInteractiveData) = accessibilityType { | ||
// If double interaction accessibility, make centerSection accessible to be focusable (isAccessibilityElement = true) | ||
centerSection.isAccessibilityElement = true | ||
// Set center section label to the provided one (or the default one if not provided) | ||
centerSection.accessibilityLabel = accessibilityInteractiveData.label ?? defaultAccessibilityLabel | ||
// Set accessibility activation action to be executed on center section double tap | ||
centerSection.accessibilityActivationAction = accessibilityInteractiveData.action | ||
Comment on lines
+23
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case of double interaction accessibility, center section has to be accessible to be focusable by VoiceOver. The label associated will be the provided one or if no label provided, the default one (defined in Figma specs) and the optional accessibility action is stored |
||
} else { | ||
// If any other accessibility type, it's managed in the superview (ListTableViewCell) | ||
centerSection.isAccessibilityElement = false | ||
centerSection.accessibilityLabel = nil | ||
centerSection.accessibilityActivationAction = nil | ||
} | ||
updateAccessibilityElements() | ||
} | ||
} | ||
|
||
// Default accessibilityLabel using the order specified in the Figma spec: | ||
// https://www.figma.com/design/Be8QB9onmHunKCCAkIBAVr/%F0%9F%94%B8-Lists-Specs?node-id=0-1&node-type=CANVAS&t=jgG9X5qKokaMwJjm-0 | ||
var defaultAccessibilityLabel: String { | ||
let titleText = titleAccessibilityLabel ?? titleAttributedText?.string ?? title | ||
let subtitleText = subtitleAccessibilityLabel ?? subtitleAttributedText?.string ?? subtitle | ||
let detailText = detailAccessibilityLabel ?? detailTextAttributedText?.string ?? detailText | ||
let headlineText = headlineView?.accessibleText | ||
|
||
let accessibilityComponents: [String?] = [ | ||
titleText, | ||
headlineText, | ||
subtitleText, | ||
detailText | ||
] | ||
Comment on lines
+48
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Composed default accessibility label following Figma specs |
||
|
||
return accessibilityComponents.compactMap { $0 }.joined(separator: ", ") | ||
} | ||
|
||
// MARK: View Styles | ||
|
||
public enum ViewStyles { | ||
|
@@ -58,7 +98,7 @@ open class ListCellContentView: UIView { | |
|
||
// MARK: SubViews | ||
|
||
/// View used in `ListCellStyle.boxed` style for show a rounded border arround the content | ||
/// View used in `ListCellStyle.boxed` style for show a rounded border around the content | ||
lazy var cellBorderView = UIView() | ||
private lazy var cellContentView = UIStackView() | ||
var tableViewDelegate: ListCellContentTableViewDelegate? | ||
|
@@ -81,7 +121,8 @@ open class ListCellContentView: UIView { | |
} | ||
set { | ||
centerSection.titleLabel.text = newValue | ||
updateAssetAligment() | ||
updateAssetAlignment() | ||
updateAccessibility() | ||
} | ||
} | ||
|
||
|
@@ -100,6 +141,7 @@ open class ListCellContentView: UIView { | |
} | ||
set { | ||
centerSection.titleLabel.attributedText = newValue | ||
updateAccessibility() | ||
} | ||
} | ||
|
||
|
@@ -117,6 +159,7 @@ open class ListCellContentView: UIView { | |
centerSection.subtitleLabel.text = newValue | ||
centerSection.didSetTextToSubtitleLabel() | ||
updateAssetView() | ||
updateAccessibility() | ||
} | ||
} | ||
|
||
|
@@ -136,6 +179,7 @@ open class ListCellContentView: UIView { | |
set { | ||
centerSection.subtitleLabel.attributedText = newValue | ||
centerSection.didSetTextToSubtitleLabel() | ||
updateAccessibility() | ||
} | ||
} | ||
|
||
|
@@ -147,6 +191,7 @@ open class ListCellContentView: UIView { | |
centerSection.detailLabel.text = newValue | ||
centerSection.didSetTexToDetailText() | ||
updateAssetView() | ||
updateAccessibility() | ||
} | ||
} | ||
|
||
|
@@ -166,16 +211,18 @@ open class ListCellContentView: UIView { | |
set { | ||
centerSection.detailLabel.attributedText = newValue | ||
centerSection.didSetTexToDetailText() | ||
updateAccessibility() | ||
} | ||
} | ||
|
||
public var headlineView: UIView? { | ||
public var headlineView: AccessibleTextualView? { | ||
get { | ||
centerSection.headlineView | ||
} | ||
set { | ||
centerSection.headlineView = newValue | ||
updateAssetView() | ||
updateAccessibility() | ||
} | ||
} | ||
|
||
|
@@ -327,12 +374,22 @@ public extension ListCellContentView { | |
} | ||
} | ||
|
||
// MARK: ListCellContentViewDelegate | ||
|
||
extension ListCellContentView: ListCellContentViewDelegate { | ||
func accessibilityChanged() { | ||
updateAccessibilityElements() | ||
} | ||
} | ||
|
||
// MARK: Private | ||
|
||
private extension ListCellContentView { | ||
func commonInit() { | ||
centerSection.listCellContentViewDelegate = self | ||
layoutViews() | ||
updateCellStyle() | ||
updateAccessibilityElements() | ||
} | ||
|
||
func layoutViews() { | ||
|
@@ -369,7 +426,7 @@ private extension ListCellContentView { | |
return | ||
} | ||
|
||
updateAssetAligment() | ||
updateAssetAlignment() | ||
|
||
leftSection.assetType = assetType | ||
|
||
|
@@ -378,11 +435,29 @@ private extension ListCellContentView { | |
} | ||
} | ||
|
||
func updateAssetAligment() { | ||
func updateAssetAlignment() { | ||
if centerSection.headlineView == nil, !centerSection.hasSubtitleText, !centerSection.hasDetailText { | ||
leftSection.centerAlignment() | ||
} else { | ||
leftSection.topAlignment() | ||
} | ||
} | ||
|
||
func updateAccessibility() { | ||
tableViewDelegate?.accessibilityChanged() | ||
} | ||
|
||
func updateAccessibilityElements() { | ||
switch accessibilityType { | ||
case .informative: | ||
// Set accessibility order following Figma spec: | ||
// https://www.figma.com/design/Be8QB9onmHunKCCAkIBAVr/%F0%9F%94%B8-Lists-Specs?node-id=0-1&node-type=CANVAS&t=jgG9X5qKokaMwJjm-0 | ||
accessibilityElements = [centerSection.titleLabel, headlineView as Any, centerSection.subtitleLabel, centerSection.detailLabel, controlView as Any].compactMap { $0 } | ||
Comment on lines
+453
to
+455
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If accessibility is informative, define elements order according Figma specs |
||
case .doubleInteraction: | ||
// If double interaction, just two elements: center section and right section | ||
accessibilityElements = [centerSection, controlView as Any].compactMap { $0 } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case of double interaction accessibility, there will be two elements: center section (which will manage it's own accessibility) and the control view |
||
case .interactive, .customInformative: | ||
accessibilityElements = [] | ||
} | ||
} | ||
} |
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.
New cell to configure accessibility
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 only see a small issue and that is that the literals can not be read as a whole.

Perhaps it would be interesting to rotate the segmented control vertically XD
https://stackoverflow.com/questions/3490358/can-i-show-an-uisegmentedcontrol-object-in-vertical
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've tried rotation with no success xD. It seems also not possible to modify segmented control to allow multiple lines. Maybe the solution is to create a new cell type for "many" options using buttons