-
Notifications
You must be signed in to change notification settings - Fork 369
Custom Controls with Xamarin Studio, and Accessibility for Calabash iOS
The Xamarin cross-platform framework provides many features, but custom controls need to be set up for accessibility.
Also be sure to check out Instrumenting your Application for Calabash iOS.
If nothing is specified for accessibility in your code, then there will be nothing displayed in the output. For our project, a custom control was created. While our code utilized the control and it was able to get and set its value and correctly display it, there was nothing picked up for its value! A query looked like this:
irb(main):057:0> query("view:'Adapx.Capturx.Tablet.ipad.Checkbox' index:0")
[
[0] {
"class" => "Adapx.Capturx.Tablet.ipad.Checkbox",
"id" => nil,
"label" => nil,
"description" => "<Adapx.Capturx.Tablet.ipad.Checkbox: 0x173ca990; baseClass = UIControl; frame = (461.55 586.131; 7.65 7.65628); layer = <CALayer: 0x173ca820>>"
}
]
While the control could be changed through touch()
, nothing was communicated about its state. Was it checked? Unchecked? And there's lots of them in the view. However, the control inherits from UIControl
, which inherits from UIView
, and UIView
contains most of the accessibility properties.
Here's the easiest to implement, just set the property with a value:
this.AccessibilityLabel = "Checkbox 1234";
This sets the language-specific label. If this was French instead of English, it might be "Case à cocher 1234." Now the query returns:
irb(main):058:0> query("view:'Adapx.Capturx.Tablet.ipad.Checkbox' index:0")
[
[0] {
"class" => "Adapx.Capturx.Tablet.ipad.Checkbox",
"id" => nil,
"label" => "Checkbox 1234",
"description" => "<Adapx.Capturx.Tablet.ipad.Checkbox: 0x173ca990; baseClass = UIControl; frame = (461.55 586.131; 7.65 7.65628); layer = <CALayer: 0x173ca820>>"
}
]
Hey, great, we're getting somewhere! But what's the value? Is that check box checked or not? The description
can be updated for that. Just override the property. You can put in anything you like in the description text.
public override string Description
{
get
{
return base.Description + string.Format("; text = Checkbox is {0}", this.IsChecked ? "checked" : "unchecked");
}
}
Now the query returns:
irb(main):059:0> query("view:'Adapx.Capturx.Tablet.ipad.Checkbox' index:0")
[
[0] {
"class" => "Adapx.Capturx.Tablet.ipad.Checkbox",
"id" => nil,
"label" => "Checkbox 1234",
"description" => "<Adapx.Capturx.Tablet.ipad.Checkbox: 0x173ca990; baseClass = UIControl; frame = (461.55 586.131; 7.65 7.65628); layer = <CALayer: 0x173ca820>>; text = Checkbox is checked"
}
]
But what about the id
? This is what Apple uses for automation. Setting id
takes a little more work, but not much. The Mono framework will map the property to the Apple [UIAccessibilityIdentification] (https://developer.apple.com/library/ios/documentation/uikit/reference/UIAccessibilityIdentification_Protocol/Introduction/Introduction.html) protocol, and set the accessibilityIdentifier
element identifier.
[Export("accessibilityIdentifier")]
public string AccessibilityIdentifier { get { return "checkbox5678"; } }
Visual Studio can add the appropriate using
statement for you, just right-click and select resolve. Now the query returns:
irb(main):060:0> query("view:'Adapx.Capturx.Tablet.ipad.Checkbox' index:0")
[
[0] {
"class" => "Adapx.Capturx.Tablet.ipad.Checkbox",
"id" => "checkbox5678",
"label" => "Checkbox 1234",
"description" => "<Adapx.Capturx.Tablet.ipad.Checkbox: 0x173ca990; baseClass = UIControl; frame = (461.55 586.131; 7.65 7.65628); layer = <CALayer: 0x173ca820>>; text = Checkbox is checked"
}
]
Now the control object is fully identified by name, and you don't need to resort to trying to figure out what is displayed where, and hoping that the index to the control doesn't change when the developers change something.