Can't get value of UIAStaticText?
Asked Answered
T

4

13

I'm trying to access the value() of a UIAStaticText (a UILabel in the objective C code) JavaScript object. I can set the value just fine using setValue() and I can confirm that the simulator updates the text, but when I try to get the value I only get null.

i.e.

text.setValue("new text");

updates the label to "new text" in the simulator.

text.value()

still returns null after I've set the value.

What am I doing wrong here?

Thegn answered 7/10, 2011 at 13:59 Comment(1)
Thank you, I was about to start banging my head against the laptopNeogene
M
15

Looks like the root of the problem is in accessibilityValue property of UILabel returning accessibilityLabel, not the UILabel text as it should. To solve this problem I override accessibilityValue property in my custom UILabel category.

@interface UILabel (MyAccessibility)
@property(nonatomic, copy) NSString *accessibilityValue;
@end


@implementation UILabel (MyAccessibility)

@dynamic accessibilityValue;

-(NSString *)accessibilityValue {
    // Here we force UIKit to return Label value, not the accessibility label 
    return self.text;
}

@end

Besides this minor trick, I always try to prefer accessibility Identifier over accessibility Label to prepare my UI elements for automated testing. Check out "Accessibility Label and Identifier Attributes" section of Instruments New Features User Guide.

Musgrove answered 22/3, 2012 at 20:48 Comment(1)
Awesome. In case anyone else is wondering what I was wondering, it turns out it's not necessary to import the category header anywhere; just compile it in your app and it works.Inesinescapable
I
12

After many hours of searching and trying things I found this on O'Reilly Answers confirming there is a bug where you cannot get a value for a static text label using Apple's UIAutomation framework. Here is the quote:

The text label string of a UILabel shows up as the StaticText field's name, not it's value, which is always nil. If you set the Accessibility label, it becomes the name property, and there is no longer any way to discover the current text in a UILabel. I have a bug report open with Apple about this.

Incentive answered 16/10, 2011 at 20:10 Comment(5)
Thanks, so it's that I set the accessibility label that borks this for me? I was thinking of reporting this as a bug, but some complications with loggin in to Apples developer portal made me forget about it.Thegn
I think automation scripts to check UILabel values are basically useless at the moment. I used the work around offered in the O'Reilly piece -- converted my UILabels to non-editable UITextFields. Trade-off is that you lose the easy formatting for things like drop shadows but otherwise worked like a charm.Incentive
You should prefer the Viktor's answer which is cleaner. You shouldn't modify your app in order to be compatible for your tests.Isidore
any updates on your bug report? Is the status of this the same?Naumann
Something new about it? can we already get the value of the UIStaticText with UIAutomation?.Ophidian
I
1

Actually, it's not necessary to create the category specified by Viktor Krykun. Setting the accessibilityIdentifier is enough -- Apple's docs say (iOS 6.1.3):

Accessibility Label and Identifier Attributes

The identifier attribute allows you to use more descriptive names for elements. It is optional, but it must be set for the script to perform either of these two operations:

  • Accessing a container view by name while also being able to access its children.
  • Accessing a UILabel view by name to obtain its displayed text (via its value attribute).

It may also be necessary to explicitly set

uilabel.accessibilityLabel = NSLocalizedString(@"Element description", @"Localized accessibility label for VoiceOver");
uilabel.accessibilityValue = uilabel.text;

In my own code I have one case where it just works, and another one where I have to explicitly set the values. My best guess at the difference is that maybe it's because I entered and then deleted the accessibility label in Interface Builder in one case -- there may end up being a difference between nil and empty string or something. Apple's code is clearly kind of fragile here (SDK 6.1.3, testing on iOS 5.0 simulator).

Inesinescapable answered 23/7, 2013 at 19:4 Comment(0)
T
1

In reply to ChrisH (since I don't see how reply to him): You could apply the same trick to UITableViewCell as to UILabel and then for a label's text inside a cell communicate with the cell for the value() instead of the static text in it. Although really it feels like piling more hacks on top of hacks. But I don't see any other way.

Edit: Added full implementation including the existing solution for completeness sake.

@interface UILabel (MyAccessibility)
@property(nonatomic, copy) NSString *accessibilityValue;
@end


@implementation UILabel (MyAccessibility)

@dynamic accessibilityValue;

-(NSString *)accessibilityValue {
    // Here we force UIKit to return Label value, not the accessibility label 
    return self.text;
}

@end


@interface UITableViewCell (AccessibilityFix)
@property(nonatomic, copy) NSString *accessibilityValue;
@end


@implementation UITableViewCell (AccessibilityFix)

@dynamic accessibilityValue;

-(NSString *)accessibilityValue {
    // Here we force UIKit to return Label value, not the accessibility label
    return self.textLabel.text;
}

@end
Turret answered 31/10, 2013 at 19:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.