21

I'm trying to access an element within a subview and I'm finding it impossible to do so.

The hierarchy being:

View Controller:

  • View
    • tempView
    • userEnterView
      • zipCodeEntered

I want to access the zipCodeEntered text field. I have an accessibility label on it named "zipCodeEntered".

When I try and record the automation, it only register the superview "userEnterView" and not the actual text field which I can tap into.

I print "app.otherElements[SUPER_VIEW_NAME].debugDescription" to see what elements are in that hierarchy and it prints none.

Any ideas as to why I can not access these elements/how I can access them? enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
sebradloff
  • 385
  • 1
  • 3
  • 10
  • Can you try setting the `accessibilityIdentifer` instead? – Joe Masilotti Sep 26 '15 at 19:59
  • Joe: I've read your UI testing blog extensively and it has help me a ton, so I just wanted to thank you for that. I added the `accessibilityIdentifier` to the zipCodeEntered textField and it still can't find it. Using either `app.otherElements["zipCodeEntered"]` or `app.textFields["zipCodeEntered"]`. Added picture of storyboard layout – sebradloff Sep 26 '15 at 23:28
  • Thanks, glad it's been helping! Have you tried accessing the element by it's placeholder text, "Zip Code"? – Joe Masilotti Sep 28 '15 at 11:21
  • Is there a way to access elements by their placeholder text straight from the app? I see app.placeholderValue exists but that just returns a string for the app's placeholder value. – sebradloff Sep 28 '15 at 22:24
  • You can use the same query you are already using. `app.textFields["Zip Code"]`. – Joe Masilotti Sep 29 '15 at 01:16
  • unfortunately `app.textfields["Zip Code"].exists` returns false. – sebradloff Sep 29 '15 at 01:36
  • This is where it can get a little odd. I've found UI testing can't identify elements by placeholder text (or label text) if you are you either using or have used accessibility ID or name. Even if you've used it once and blanked it out. You have to go to the storyboard XML and literally manually delete it the accessibility XML for that UI element. I've opened an apple bug and I believe they've accepted it's an open issue. Once the storyboard accessibility XML is no longer there, there is simply no reason why `app.textFields["Zip Code"].exists` shouldn't work. Let me know if that helps! – Nick McConnell Sep 29 '15 at 02:53
  • I deleted all the accesibility code from the XML and still no joy. I then proceeded to delete the text field and add it again, with just the placeholder "Zip Code", still nothing... Have you noticed this as an issue with elements located within subviews? Thanks for all your help! – sebradloff Sep 30 '15 at 02:52

3 Answers3

36

The subviews are not accessible because the parent view is not a container view. From the section Making Your iOS App Accessible from the Accessibility Programming Guide:

From the perspective of accessibility, a custom view is either an individual view or a container view. An individual view does not contain any other views that need to be accessible.

A container view, on the other hand, contains other elements with which users can interact.

To make the subviews accessible the parent view should tell UIAccessibility that it is an accessibility container by returning NO from -isAccessibilityElement and implementing the methods of the UIAccessibilityContainer protocol.

Community
  • 1
  • 1
quellish
  • 21,123
  • 4
  • 76
  • 83
  • 4
    Thank you! That was exactly the problem. There are two ways of achieving this. 1) uncheck accessibility for all the view elements that I had. 2) programmatically, in the view controller use the specific view outlet to write `viewOutletVariable.isAccessibilityElement = false`. – sebradloff Oct 06 '15 at 22:00
  • 1
    This answer was basically acted as an inhaler for me. – Michael Ramos May 02 '17 at 17:29
  • UIAccessibilityContainer is only for views that contain non UIKit backed elements. For example drawing text and images manually with `drawAtPoint` rather than a UILabel or UIImageView. – Jonathan. Oct 26 '17 at 12:40
  • @Jonathan. UIAccessibilityContainer is "methods can be overridden to vend individual elements that are managed by a single UIView.". For example, the iOS dialing interface may be a view that implements `UIAccessibilityContainer` to allow accessibility to interact individually with the UIButtons it contains, rather than the parent view that contains them. – quellish Oct 29 '17 at 06:31
  • 1
    This solves the problem. Just set `isAccessibilityElement = false` on any custom view that is containing other elements. I owe you a beer in this or in another life. – Fmessina Oct 27 '18 at 12:58
0

The thing that fixed it for me was to check √ the "Accessibility" box to enabled in Interface Builder.

enter image description here

If not working in IB try setting the the view's isAccessibilityElement property to true.

Hope that helps!

Patrick Ridd
  • 401
  • 6
  • 4
-1

I also encountered this problem in my UITableView. My cell has a containerView(UIView) which has subviews(TextView, UIButton...) and a collectionView with its cells.

I tried the accepted answer, but it didn't work.(UI Recorder or manual code didn't recognize my sub-elements). But sometimes I found the UITest suddenly recognized my sub-elements when I triggered something to refresh the table.

So right now I know if UITest can't find my subviews, I invoke tableView.reloadData to refresh the view, and then all the problem is gone.

Anyway, this is just a workaround, I hope Apple can fix it as soon as possible.

Andres Wang
  • 295
  • 3
  • 4
  • How do you invoke tableView.reloadData in XCUI? – Ishmeet Feb 14 '17 at 16:36
  • This answer is in no way related to the question, as the code and the screenshot show there is no `UITableView` involved at all. – Max Desiatov Apr 22 '17 at 12:21
  • Even though this is not really related to the original question, I've found this helpful because I was having the same issue - XCUI didn't find any cells inside the table though there were cells on the snapshot at that moment. Reloading the table view helped. I've used https://github.com/Subito-it/SBTUITestTunnel for this. I hope XCode will fix this soon. – Artem Aleksandrov Jun 25 '18 at 08:20