简体   繁体   中英

UIPageControl and VoiceOver/accessibility

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.

I still needed to implement the Custom AccessiblePageControl using iOS 10+ (as suggested above). I followed the approach above but linked an IBAction on my storyboard for both touchUpInside and valueChanged.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM