When using voice over on the springboard, when the UIPageControl at the bottom of the screen is selected, VoiceOver announces something like "Page 1 of 5. Adjustable." and the user can swipe up and down to change pages.
In my app, I do not get the "Adjustable" part, and the pages cannot be changed by swiping.
Any ideas how I fix this? It obviously kills the usability of the app.
I have subclassed UIPageControl
and overrode the -accessibilityTraits
getter to return UIAccessibilityTraitAdjustable
getting Voice Over to read "adjustable".
To add actions: implement the -accessibilityIncrement
and -accessibilityDecrement
methods specified in the UIAccessibilityAction
category.
Since my pages respond to the UIControlEventValueChanged
events, I make sure to send actions for this event too.
Sample code
@interface AccessibleUIPageControl : UIPageControl
@end
@implementation AccessibleUIPageControl
- (UIAccessibilityTraits)accessibilityTraits
{
return super.accessibilityTraits | UIAccessibilityTraitAdjustable;
}
- (void)accessibilityIncrement
{
self.currentPage = self.currentPage + 1;
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
- (void)accessibilityDecrement
{
self.currentPage = self.currentPage - 1;
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
@end
If you're supporting iOS 9 and newer, this behavior is now the standard - no special handling required.
If you're supporting iOS 8 and lower, subclass UIPageControl
and override accessibilityIncrement
and accessibilityDecrement
. You don't need to override the accessibilityTraits
property to indicate it's adjustable - UIPageControl
is adjustable by default.
import UIKit
class AccessibleUIPageControl: UIPageControl {
override func accessibilityIncrement() {
self.currentPage += 1
self.sendActionsForControlEvents(.ValueChanged)
}
override func accessibilityDecrement() {
self.currentPage -= 1
self.sendActionsForControlEvents(.ValueChanged)
}
}
Then in your view controller you can listen for ValueChanged and respond appropriately to show the content for the new page:
//viewDidLoad:
self.pageControl.addTarget(self, action: "didChangePage", forControlEvents: .ValueChanged)
func didChangePage() {
let contentOffset: CGFloat = collectionView.frame.size.width * CGFloat(pageControl.currentPage)
collectionView.setContentOffset(CGPointMake(contentOffset, 0), animated: false)
}
Note that if you don't subclass UIPageControl
this target/action will still be called but the current page dot indicator will not update.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With