Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VoiceOver does not consistently focus on UILabel when when view is presented

We have a login screen with a UILabel hidden initially to represent a message when the user logs out of the app.

When VoiceOver is turned on in iOS and the user tries to log out from the app, the voice over should ideally read out the logout message label. Instead, it reads out the password text field of the login screen.

The action of the log out button has the below implementation code.

let loginStoryboard = UIStoryboard(name: "Login", bundle: nil)
        let loginViewController = loginStoryboard.instantiateInitialViewController() as! LoginViewController
        loginViewController.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
loginViewController.logOut = true
self.presentViewController(loginViewController, animated: true, completion:nil)

The logout indicator is set to display the logout message label. LoginViewController viewDidLoad code.

if(!logOut){
            self.logOutMsg.hidden = true
}else{
            self.logOutMsg.text = NSLocalizedString("LoggedOutMsg", comment: "Logged out message")
            self.logOutMsg.hidden = false
}

The login screen fields are accessibility enabled in story board.

The behavior is inconsistent: sometimes the logout message label is read and sometimes it reads out the password text field. Whenever VoiceOver reads the password text field, I can see an error in the console log.

 |error| Could not find <UIWindow: 0x124d13b10; frame = (0 0; 768 1024); gestureRecognizers = <NSArray: 0x174241140>; layer = <UIWindowLayer: 0x1742319c0>> in a list of sorted view [parent: <CaseworkerApp.AppDelegate: 0x124e008e0>] siblings (
        "<UILabel: 0x124d06cf0; frame = (132 1; 300 18); text = 'You are logged out of IBM...'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1742921b0>>",
        "<CaseworkerApp.LoginTextField: 0x124da4890; baseClass = UITextField; frame = (80 37; 330 50); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x1704551e0>; layer = <CALayer: 0x175033de0>>",
        "<CaseworkerApp.LoginTextField: 0x124d9bd50; baseClass = UITextField; frame = (80 110; 330 50); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; tag = 1; gestureRecognizers = <NSArray: 0x17044dfb0>; layer = <CALayer: 0x175227ce0>>",
        "<UIButton: 0x124d52900; frame = (80 183; 330 50); autoresize = RM+BM; layer = <CALayer: 0x175039ae0>>"
    ).  If this happened right around a screen change, it might be okay, but otherwise this is probably a bug.
    2015-08-10 16:46:50.108 CaseworkerApp[2217:479225] |error| Could not find <UIWindow: 0x124d13b10; frame = (0 0; 768 1024); gestureRecognizers = <NSArray: 0x174241140>; layer = <UIWindowLayer: 0x1742319c0>> in a list of sorted view [parent: <CaseworkerApp.AppDelegate: 0x124e008e0>] siblings (
        "<UILabel: 0x124d06cf0; frame = (132 1; 300 18); text = 'You are logged out of IBM...'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1742921b0>>",
        "<CaseworkerApp.LoginTextField: 0x124da4890; baseClass = UITextField; frame = (80 37; 330 50); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x1704551e0>; layer = <CALayer: 0x175033de0>>",
        "<CaseworkerApp.LoginTextField: 0x124d9bd50; baseClass = UITextField; frame = (80 110; 330 50); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; tag = 1; gestureRecognizers = <NSArray: 0x17044dfb0>; layer = <CALayer: 0x175227ce0>>",
        "<UIButton: 0x124d52900; frame = (80 183; 330 50); autoresize = RM+BM; layer = <CALayer: 0x175039ae0>>"
    ).  

If this happened right around a screen change, it might be okay, but otherwise this is probably a bug.

Any help please to resolve this?

like image 735
Suresh Subbaiah Avatar asked Aug 10 '15 11:08

Suresh Subbaiah


1 Answers

When a view is presented, VoiceOver starts reading from the first element in the accessibility tree. There are possibly two solutions.

First, you can modify the order.

Change order of read items with VoiceOver

Secondly, you can make VoiceOver to focus on a particular element when a view changes by posting ScreenChanged Notification from UIAccessibility indicating which element VoiceOver should focuss.

UIAccessibility.post(notification:.screenChanged, argument:elementToBeFocussed)

Read more information from the documentation.

UIAccessibility.post: https://developer.apple.com/documentation/uikit/uiaccessibility/1615194-post

UIAccessibility.Notification: https://developer.apple.com/documentation/uikit/uiaccessibility/notification

screenChanged: https://developer.apple.com/documentation/uikit/uiaccessibility/notification/1620198-screenchanged

like image 70
jl303 Avatar answered Nov 18 '22 09:11

jl303