Skip to content

Commit 5e85f74

Browse files
committed
Bug 1158509 - Reading List item does not announce if it is read/unread
with accessibility We communicate that the item is read primarily by speaking it with lower pitch. So a VoiceOver user immediately learns whether item is read/unread by noting the pitch of the voice. As read/unread status is not communicated by a word at the beginning of the accessibility label and the label begins with the title of the webpage, the user will also immediately learn the beginning words of the title of webpage. I.e., the title of the webpage and read/unread status are learned simultaneously and immediately by the VoiceOver user. This allows for quick navigation through the items, as within first fractions of a second VoiceOver user can identify both read/unread status and the beginning of the title of the article. "Read"/"Unread" is still announced after the title, in case the user is using only braille display without speech, or the user has trouble recognizing pitch changes, or the user is a Switch Control user (Switch Control does not respect the UIAccessibilitySpeechAttribute* attributes - <rdar://problem/20701917>).
1 parent c2628e1 commit 5e85f74

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

Client/Frontend/Home/ReaderPanel.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ private struct ReadingListTableViewCellUX {
1616

1717
static let ReadIndicatorWidth: CGFloat = 16 + 16 + 16 // padding + image width + padding
1818
static let ReadIndicatorHeight: CGFloat = 14 + 16 + 14 // padding + image height + padding
19+
static let ReadAccessibilitySpeechPitch: Float = 0.7 // 1.0 default, 0.0 lowest, 2.0 highest
1920

2021
static let TitleLabelFont = UIFont(name: UIAccessibilityIsBoldTextEnabled() ? "HelveticaNeue-Bold" : "HelveticaNeue-Medium", size: 15)
2122
static let TitleLabelTopOffset: CGFloat = 14 - 4
@@ -45,12 +46,14 @@ class ReadingListTableViewCell: SWTableViewCell {
4546
var title: String = "Example" {
4647
didSet {
4748
titleLabel.text = title
49+
updateAccessibilityLabel()
4850
}
4951
}
5052

5153
var url: NSURL = NSURL(string: "http://www.example.com")! {
5254
didSet {
5355
hostnameLabel.text = simplifiedHostnameFromURL(url)
56+
updateAccessibilityLabel()
5457
}
5558
}
5659

@@ -61,6 +64,7 @@ class ReadingListTableViewCell: SWTableViewCell {
6164
hostnameLabel.textColor = unread ? ReadingListTableViewCellUX.ActiveTextColor : ReadingListTableViewCellUX.DimmedTextColor
6265
markAsReadButton.setTitle(unread ? ReadingListTableViewCellUX.MarkAsReadButtonTitleText : ReadingListTableViewCellUX.MarkAsUnreadButtonTitleText, forState: UIControlState.Normal)
6366
markAsReadAction.name = markAsReadButton.titleLabel!.text
67+
updateAccessibilityLabel()
6468
}
6569
}
6670

@@ -169,6 +173,27 @@ class ReadingListTableViewCell: SWTableViewCell {
169173
self.delegate?.swipeableTableViewCell?(self, didTriggerRightUtilityButtonWithIndex: 0)
170174
return true
171175
}
176+
177+
private func updateAccessibilityLabel() {
178+
if let hostname = hostnameLabel.text,
179+
title = titleLabel.text {
180+
let unreadStatus = unread ? NSLocalizedString("unread", comment: "Accessibility label for unread article in reading list. It's a past participle - functions as an adjective.") : NSLocalizedString("read", comment: "Accessibility label for read article in reading list. It's a past participle - functions as an adjective.")
181+
let string = "\(title), \(unreadStatus), \(hostname)"
182+
var label: AnyObject
183+
if !unread {
184+
// mimic light gray visual dimming by "dimming" the speech by reducing pitch
185+
let lowerPitchString = NSMutableAttributedString(string: string as String)
186+
lowerPitchString.addAttribute(UIAccessibilitySpeechAttributePitch, value: NSNumber(float: ReadingListTableViewCellUX.ReadAccessibilitySpeechPitch), range: NSMakeRange(0, lowerPitchString.length))
187+
label = NSAttributedString(attributedString: lowerPitchString)
188+
} else {
189+
label = string
190+
}
191+
// need to use KVC as accessibilityLabel is of type String! and cannot be set to NSAttributedString other way than this
192+
// see bottom of page 121 of the PDF slides of WWDC 2012 "Accessibility for iOS" session for indication that this is OK by Apple
193+
// also this combined with Swift's strictness is why we cannot simply override accessibilityLabel and return the label directly...
194+
setValue(label, forKey: "accessibilityLabel")
195+
}
196+
}
172197
}
173198

174199
class ReadingListPanel: UITableViewController, HomePanel, SWTableViewCellDelegate {

0 commit comments

Comments
 (0)