Skip to content
This repository has been archived by the owner on Nov 27, 2018. It is now read-only.

Igor Usage Tips

dhemery edited this page May 6, 2012 · 9 revisions

Reading Igor Queries

There are two directions to read an Igor query: from left to right, and from right to left. If a query is difficult to understand when you read it in one direction, try reading it in the other.

Consider this example:

UIScrollView > * > [accessibilityLabel == 'cows']

We can read this from left to right as a procedure for finding the views we're interested in:

  1. Find every UIScrollView
  2. Then find all of the children of those views.
  3. Then find the children of those views whose accessibilityLabel is 'cows'.

We can also read the query from right to left, as a description of the views we're interested in:

Every view whose accessibilityLabel is 'cows',


... and is a child of any view
... that is a child of a `UIScrollView`.

We can shorten this to:

Every view whose accessibilityLabel is 'cows',


... and is a grandchild of a UIScrollView.

Finding Views Based On Descendants

Sometimes you want to find a view based on properties of its descendants.

Suppose your app displays a table, and one of the cells in the table contains a view identified (by its accessibilityIdentifier property) as 'Barney'.

And suppose you want to find the table view cell that contains the Barney view. You can do that by using a subject marker:

$UITableViewCell #Barney

This query tells Igor to find every place in the view hierarchy where a UITableViewCell has a descendant #Barney. The dollar sign tells Igor to select the table cells.

Subject markers change the way you read a query. You can read this query from left to right like this:

A UITableViewCell


... that contains a descendant whose `accessibilityIdentifier` is 'Barney'.

Cousins! Finding Views Based On Common Ancestry

Sometimes you want to find a view based on its relationship to some other view that has a common ancestor.

Suppose your app displays a table and you've already tapped the Edit button to enter edit mode:

A table in edit mode

Now suppose you want to delete the row labeled '2'. To do this, you have to find the delete button for that row. Here is part of the view hierarchy:

View hierarchy for a table in edit mode

We know some facts about the delete button:

  • Its class is UITableViewCellEditControl
  • Its text is 'Delete '

We can use either of these facts to locate the button. But notice that there are several other buttons with the same features. The facts we know about the delete button do not uniquely identify the one we want to tap.

But we do know that the delete button we want to tap is in the same row as the UILabel with text '2'. With this information, we can construct a query that says "select the delete button that is in the same table cell as the row labeled '2'."

To construct such a query, we first need to identify three pieces:

  • The target view—the view that we ultimately want to select. In our example, the target view is a view whose class is UITableViewCellEditControl.

  • A reference view—some view that we know how to find, and that bears a meaningful relationship to the target view. In our example, the reference view is a UILabel with text '2'.

  • A common ancestor—a view that contains both the target view and the reference view. In our example, the nearest common ancestor is the UITableViewCell that contains the UILabel whose text is '2'.

Here are the steps to build up the query from these pieces:

  1. Write a query that selects the reference view, like this:

    UILabel[text == '2']

  2. Prepend patterns to show the reference view's relationship to the common ancestor:

    UITableViewCell UILabel[text == '2']

  3. Wrap the query in parentheses to form a branch pattern:

    (UITableViewCell UILabel[text == '2'])

    This branch pattern all by itself is equivalent to: $UITableViewCell UILabel[text == '2']. It selects the table view cell that is an ancestor of the label with text '2'. That is: It selects our desired common ancestor.

  4. Append the relationship between the common ancestor and the target view:

    (UITableViewCell UILabel[text == '2']) UITableViewCellEditControl

And there you have it: Cousins! A query that selects a view based on its relationship to some other view within a common ancestor.