Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS get UINavigationBar's back button in order to set accessibility properties

I have a navigation controller stack where one of the views has a dynamic title.

The view controllers and their titles go like this:

Main       -->  ItemsTableView  -->  ItemDetails
Title:Main      Title: NN Items      Title: Details

Because the iOS UINavigationController sets the text of the "Back" button to be the title of the previous screen, the "Back" button on the details screen says "< NN Items" where NN is a dynamically changing number.

I'm trying to do some iOS UI automation, but the accessibility Label / ID of the back button is set by the system to it's button text. This means that the accessibility label of the back button on the details screen will change dynamically, and I can't find it from my scripts!

If I could get a reference to the UIBarButtonItem then I could easily set it's accessibilityLabel or accessibilityIdentifier from code to be a fixed string, however I can't figure out how to do this?

All of the stuff I've been able to find references setting the back button to a custom button via self.navigationItem.backBarButtonItem or similar, but when I read this property it's nil. I haven't been able to find out how to get access to the standard item without replacing it. I'd prefer not to replace the button if possible

like image 303
Orion Edwards Avatar asked Jun 20 '14 01:06

Orion Edwards


1 Answers

This was bugging me as well. I've been writing Xcode 7 UI Tests and was trying to come up with a generic way of tapping on the back button without having to replace it with a custom button.

The following is how I solved this for Xcode 7 UI Tests - but you may also be able to apply this to UI Automation as well.

I discovered that (in terms of Xcode 7 UI Tests at least) the back bar button item that is created by the system consists of two buttons the entire thing is a button with an accessibility label of whatever the title of the button is, and then the arrow is also a button with an accessibility label of "Back".

Thus, as long as there aren't any other buttons on the screen that are identified as "Back", the back button can be accessed via the accessibility label of "Back". Like so in the case of UI Tests:

[[app.buttons matchingIdentifier:@"Back"] elementBoundByIndex:0]

Here I'm getting the first button that can be identified by "Back". I my case there could only ever be two such buttons - the arrow, or the whole back button itself (in the case where the back button's title is also "Back"). Since both of these buttons are essentially the same, just getting the first one it finds is sufficient.

like image 137
David Bagwell Avatar answered Nov 19 '22 02:11

David Bagwell