@@ -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
@@ -60,9 +63,14 @@ class ReadingListTableViewCell: SWTableViewCell {
6063 titleLabel. textColor = unread ? ReadingListTableViewCellUX . ActiveTextColor : ReadingListTableViewCellUX . DimmedTextColor
6164 hostnameLabel. textColor = unread ? ReadingListTableViewCellUX . ActiveTextColor : ReadingListTableViewCellUX . DimmedTextColor
6265 markAsReadButton. setTitle ( unread ? ReadingListTableViewCellUX . MarkAsReadButtonTitleText : ReadingListTableViewCellUX . MarkAsUnreadButtonTitleText, forState: UIControlState . Normal)
66+ markAsReadAction. name = markAsReadButton. titleLabel!. text
67+ updateAccessibilityLabel ( )
6368 }
6469 }
6570
71+ private let deleteAction : UIAccessibilityCustomAction
72+ private let markAsReadAction : UIAccessibilityCustomAction
73+
6674 let readStatusImageView : UIImageView !
6775 let titleLabel : UILabel !
6876 let hostnameLabel : UILabel !
@@ -75,6 +83,8 @@ class ReadingListTableViewCell: SWTableViewCell {
7583 hostnameLabel = UILabel ( )
7684 deleteButton = UIButton ( )
7785 markAsReadButton = UIButton ( )
86+ deleteAction = UIAccessibilityCustomAction ( )
87+ markAsReadAction = UIAccessibilityCustomAction ( )
7888
7989 super. init ( style: style, reuseIdentifier: reuseIdentifier)
8090
@@ -117,6 +127,9 @@ class ReadingListTableViewCell: SWTableViewCell {
117127 deleteButton. setTitle ( ReadingListTableViewCellUX . DeleteButtonTitleText, forState: UIControlState . Normal)
118128 deleteButton. setTitleColor ( UIColor . whiteColor ( ) , forState: UIControlState . Normal)
119129 deleteButton. titleEdgeInsets = ReadingListTableViewCellUX . DeleteButtonTitleEdgeInsets
130+ deleteAction. name = deleteButton. titleLabel!. text
131+ deleteAction. target = self
132+ deleteAction. selector = " deleteActionActivated "
120133 rightUtilityButtons = [ deleteButton]
121134
122135 markAsReadButton. backgroundColor = ReadingListTableViewCellUX . MarkAsReadButtonBackgroundColor
@@ -127,7 +140,12 @@ class ReadingListTableViewCell: SWTableViewCell {
127140 markAsReadButton. setTitle ( ReadingListTableViewCellUX . MarkAsReadButtonTitleText, forState: UIControlState . Normal)
128141 markAsReadButton. setTitleColor ( UIColor . whiteColor ( ) , forState: UIControlState . Normal)
129142 markAsReadButton. titleEdgeInsets = ReadingListTableViewCellUX . MarkAsReadButtonTitleEdgeInsets
143+ markAsReadAction. name = markAsReadButton. titleLabel!. text
144+ markAsReadAction. target = self
145+ markAsReadAction. selector = " markAsReadActionActivated "
130146 leftUtilityButtons = [ markAsReadButton]
147+
148+ accessibilityCustomActions = [ deleteAction, markAsReadAction]
131149 }
132150
133151 required init ( coder aDecoder: NSCoder ) {
@@ -145,6 +163,37 @@ class ReadingListTableViewCell: SWTableViewCell {
145163 }
146164 return hostname
147165 }
166+
167+ @objc private func markAsReadActionActivated( ) -> Bool {
168+ self . delegate? . swipeableTableViewCell ? ( self , didTriggerLeftUtilityButtonWithIndex: 0 )
169+ return true
170+ }
171+
172+ @objc private func deleteActionActivated( ) -> Bool {
173+ self . delegate? . swipeableTableViewCell ? ( self , didTriggerRightUtilityButtonWithIndex: 0 )
174+ return true
175+ }
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+ }
148197}
149198
150199class ReadingListPanel: UITableViewController, HomePanel, SWTableViewCellDelegate {
0 commit comments