I. Open the Blind mode:

Mobile phone (6s iOS12.4) Path: Settings -> General -> Accessibility (bottom) -> Accessibility Shortcuts -> Select voiceOver



There is also a voice-over option at the top of the Accessibility page in the General list, but it’s best to turn voice-over on the way I’ve illustrated it. Because, as the red box out according to this way I open narrator function can be directly shortcuts (even by three home button below) open closed, enhance the efficiency of this in your development isn’t a packet, because the use of the blind mode with the normal gap is larger, such as you to debug a deeper level of the page, You can enter the destination page in the normal way and then press the home button three times to start the narration. If you open the voice-over in a different way without opening the shortcut key, you have to go to the destination page in blind mode, which is quite painful.

Second, attribute interpretation

  • IsAccessibilityElement Sets whether blind mode is supported. It must be set to YES to focus on this element. Note that UIView is turned off by default, UIButton and UILabel are turned on by default.
  • AccessibilityLabel describes what the control is. UIButton and Lable are fetched from title and text by default, and textField is fetched from the contents of the input field.. The element is played first when it gets focus.
  • AccessibilityTraits Attributes of an element. Buttons, links, etc. The element gets focus and plays in the second. Since it will play buttons, etc., accessibilityLabel can directly use system description features without adding link description, such as: Lable for login,traint for button, system will play “login -> button”.
  • AccessibilityHint is quite a footnote. The third reads aloud and defaults to nil.
  • AccessibilityValue Specifies the value of the element. Used in UISlider,UITextField and other components. The value used to describe the element.
  • AccessibilityFrame The frame of the element. When the system focuses on the current element, there is a black outer frame. This value is the size of the focus frame. When the element is too small, you can set this frame to make it easy to click, and this will not change the UI of your app. If you don’t want the system to read this element, you can set the frame to CGRectZero.

Three, special treatment

  1. If it is a commodity list page, the corresponding cell only needs to set itself as an ease-of-use element if it wants to output the prompt text directly after being focusedself.isAccessibilityElement = YES;Then set up a prompt copy where you can get the business data:self.accessibilityLabel = [NSString stringWithFormat:@"product name %@ %@",eventProduct.name,self.priceLbl.attributedText.string];
  2. Some views, if you draw them yourself, like the pay button at the bottom of the shopping cart in our App, that’s drawn with UIBezierPath. It’s a little bit more cumbersome. Need to implement a definition inUIAccessibilityContainer.h  The informal protocol in the file does not need to follow the protocol with Angle brackets, but simply implements the following methods. Although the system focus frame is slightly different from the actual shape of the button, the effect is not significant. Fortunately, in this case, the original defined click event does not need special handling.

    - (BOOL)isAccessibilityElement {    
        return NO;
    }     
    - (NSArray *)accessibilityElements {    
        return self.accessArray;
    }
    - (NSInteger)accessibilityElementCount {    
        return self.accessArray.count;
    }     
    
    @property (nonatomic, strong) NSArray           *accessArray;     
    - (NSArray *)accessArray {    
        if (_accessArray) {        
            return _accessArray;    
        }    
        UIAccessibilityElement *ele1 = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self.bgView];    
        CGRect rect1 = CGRectMake(CGRectGetMinX(self.bgView.frame), CGRectGetMinY (self) bgView) frame), CGRectGetWidth (self) bgView) frame) / 2.0, CGRectGetHeight (self) bgView) frame)); ele1.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(rect1, self.bgView); ele1.accessibilityLabel = @"PayPal"; / / here with the best, because the blind users is a button to hear that, just know it can click ele1 accessibilityTraits = UIAccessibilityTraitButton; UIAccessibilityElement *ele2 = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self]; CGRect rect2 = CGRectMake(CGRectGetMidX(self.bgView.frame), CGRectGetMinY (self) bgView) frame), CGRectGetWidth (self) bgView) frame) / 2.0, CGRectGetHeight (self) bgView) frame)); ele2.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(rect2, self.bgView); ele2.accessibilityLabel = PPString(SHOPPINGCART_PROCEEDTOCHECKOUT); ele2.accessibilityTraits = UIAccessibilityTraitButton; _accessArray = @[ele1, ele2];return _accessArray;
    }Copy the code




  3. Changes in focus after a process interruption. When entering a new screen, the system defaults to focusing on the first element in the upper left corner, usually a close button or exit button. According to our business process, the user must log in before checkout to execute the subsequent process. So if a blind visitor adds an item to the shopping cart, click checkout. The login and registration window will pop up first for them to log in. Using the system’s default focus Settings would be very unfriendly: the user would hear the checkout button and then click on it and hear the Close button. So we’d better adjust the focus manually here. Treatment: I directly set the accessibilityLabel of the textField in the account input field to @”Welcome, sign in or register to continue shopping.” Then login register controller viewDidAppear invokes the method UIAccessibilityPostNotification (UIAccessibilityScreenChangedNotification, self.signInDataSource.emailTextField); Focus the interface on the account entry field.

  4. In some special process stages, the data will be lost after the user returns, so when he clicks the back button, there will be a confirmation popup. Many confirmation pop-ups in the current project are written by us in the style of UIAlertView, and then added to the root window. So we need to do something special here, otherwise it’s hard to switch to our custom popover from the left and right swipe gesture. The core method is the same as above, After custom popup window is added to the root window call UIAccessibilityPostNotification (UIAccessibilityScreenChangedNotification, alertVew. TitleLbl); Method to focus on the popover title.


Write at the end

This is my little experience in blind mode adaptation. The information I searched on the Internet before is relatively small and old, so I want to record the problems ENCOUNTERED, and it will be better if I can happen to help a friend who encountered this problem. The reason for the sudden adaptation of the blind mode is actually that our App and website were accused in the United States of not supporting the use of the blind, so we just adapted the main process of shopping order, without making any details. You might want to read the UISwings.h file in UIKit yourself if you get into more detail and depth.



Five, the complement

The screen focus changes due to flow switching and voice prompt is required. It appears on the details page of our App. The specific situation is that when you click the purchase button on the details page, a half-popup window will pop up, allowing the user to select the color, size, quantity, etc.



Click “confirm”, close the half-popup window and set the focus on the “Add” button on the details page; At the same time, the product requires a voice feedback of “Add to Cart successfully”.



So now the problem is how to Add the voice feedback of “Add to Cart successfully” when the focus of the screen is changed from the “Add to Cart, Button” to the “Add to Cart successfully” Button in the details page (at this time, the system reading prompt is “Add to Cart, Button”). At first I found UIAccessibilityConstants. H file UIAccessibilityElementFocusedNotification, equivalent to focus on the screen switch will be notified. Underneath it are two more things:

// The corresponding value is the element that is now focused by the assistive technology.
UIKIT_EXTERN NSString *const UIAccessibilityFocusedElementKey NS_AVAILABLE_IOS(9_0);

// The corresponding value is the element that had previously been focused by the assistive technology.
UIKIT_EXTERN NSString *const UIAccessibilityUnfocusedElementKey NS_AVAILABLE_IOS(9_0);Copy the code

It’s easy to see from the notes that the three of them are used together. So my solution is details page registered UIAccessibilityElementFocusedNotification notice, at the time of receiving the notice, with the two key to focus before and after the switching elements, if qualified, will delay to send a voice prompt. The main code is as follows:

// Notification of screen focus switch in blind mode [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(postAddToCartSuccessedVoiceTips:) name:UIAccessibilityElementFocusedNotification object:nil]; - (void)postAddToCartSuccessedVoiceTips:(NSNotification *)noti { UIButton *previous = noti.userInfo[UIAccessibilityUnfocusedElementKey]; UIButton *current = noti.userInfo[UIAccessibilityFocusedElementKey]; BOOL previousIsAddToCart = ISCLASS([UIButton class], previous) && ([previous.currentTitle isEqualToString:PPString(OK_STRING)] || [previous.currentTitle isEqualToString:PPString(PRODUCTDETAIL_ADDTOCART)]); BOOL currentIsAddToCart = ISCLASS([UIButton class], current) && [current.currentTitle isEqualToString:PPString(PRODUCTDETAIL_ADDTOCART)];if(previousIsAddToCart && currentIsAddToCart) {// Determine the screen focus from the AddToCart button To the details page, Dispatch_after (dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, kAddToCartSuccessedTips); }); }}Copy the code

One problem with this crude approach is that if you don’t finish reading “Add to Cart, Button” in 2.5 seconds, your subsequent voice prompt interrupts what you are reading. Or if you read “Add to Cart, Button” at a fast pace, you’ll have to wait a few tenths of a second before you hear the added order. So this is an inelegant solution. If you have a better solution, please feel free to comment!