How can I make an SLTextField tappable? - objective-c

I have been writing a test with "Subliminal's" "SLTextField" and have run into some really annoying issues lately.
I have written a test which should update a text field, clear it, and update it again.
For some reason when I use "SLTextField" to change the element text I consistently receive errors stating that "SLTextFields" aren't tappable elements. Is this true? If so, what is the point of having an "SLTextField" class at all?
I can rewrite the same test code to find the element as an "SLElement", at which point I can tap the element, open up a keyboard object and type the necessary text, but it seems like I'm circumventing the entire functionality of Subliminal in doing this.
What's wrong w/"SLTextField"?
Code:
SLTextField *textField = [SLTextField elementWithAccessibilityLabel:fieldName];
SLWaitUntilTrue([textField isTappable], DEFAULT_TIMEOUT);
textField.text = newValue;
The above code throws an error, stating that "textField" never becomes tappable. Alternatively, the code below works perfectly, though it's unnecessarily verbose and seems to make "SLTextField" superfluous.
Code:
SLElement *field = [SLElement elementWithAccessibilityLabel:fieldName];
[field tapAtActivationPoint];
//fill with text
SLKeyboard *kb = [SLKeyboard keyboard];
SLKeyboardKey *deleteKey = [SLKeyboardKey elementWithAccessibilityLabel:#"Delete"];
while(![field.value isEqualToString:#""]){
[deleteKey touchAndHoldWithDuration:1.2];
}
[kb typeString:newValue];
SLKeyboardKey *doneKey = [SLKeyboardKey elementWithAccessibilityLabel:#"Next"];
if(![doneKey isValid]){
doneKey = [SLKeyboardKey elementWithAccessibilityLabel:#"Done"];
}
[doneKey tap];
[kb hide];

Is your TextField within a TableViewCell? And are you seeing this on iOS 7?
If so, it might have been fixed by https://github.com/inkling/Subliminal/pull/202 (merged 6/6/2014).

Related

Kotlin button listener

I want to increase the value of i every time the button is clicked
I've tried this code but it's not working.
val textview = findViewById<TextView>(R.id.texttest)
var i = 10
bookbutton.setOnClickListener {
i++
}
textview.text = "$i"
You have to set the text inside the listener:
bookbutton.setOnClickListener {
i++
textview.text = "$i"
}
Your listener is updating the value of i — but that's not having any visible effect because by then it's too late: the text shown in your textview has already been set.
Let's review the order of events:
Your code runs. That creates a text view and a variable, sets a listener on the button, and sets the text in the text view.
At some later point(s), the user might click on the button. That calls the listener, which updates the variable.
So while your code sets the listener, the listener does not run until later. It might not run at all, or it might run many times, depending on what the user does, but it won't run before you set the text in the text view.
So you need some way to update the text when you update the variable. The simplest way is to do explicitly it in the listener, e.g.:
bookbutton.setOnClickListener {
textview.text = "${++i}"
}
(There are other ways — for example, some UI frameworks provide ways to ‘bind’ variables to screen fields so that this sort of update happens automatically. But they tend to be a lot more complex; there's nothing wrong with the simple solution.)

replacement for tabbar selected index

I have an old app where I have 5 tabs. Each tab have list of ads & there is details. Also each tab have respective add ad. Design for all 5 tabs is same except some changes, so I decided to use 1 screen only for all 5 tabs.
Now what I am doing is while add ad, I am checking which tab I am and based on tab bar index, I am showing hiding fields. Same is applicable for details screen also. Sample code is as shown below.
if (self.tabBarController.selectedIndex==0) {
field1.hidden = NO;
} else if (self.tabBarController.selectedIndex==1) {
field1.hidden = NO;
} else if (self.tabBarController.selectedIndex==2) {
field1.hidden = NO;
} else if (self.tabBarController.selectedIndex==3) {
field1.hidden = NO;
} else if (self.tabBarController.selectedIndex==4) {
field1.hidden = YES;
}
Now I have around 15 fields for each form so I write this code for all fields.
What I noticed that client change the tab bar position continuously so I was looking for efficient way of doing it.
Right now what I do is at all places manually change index positions by doing Search-Replace, however I dont like this.
I was looking for a way where instead of selectedIndex, I was looking for someconstant value that I will assign to tab item of tab bar, so my code will change as below
if (self.tabBarController.selectedIndex==adType_News) {
field1.hidden = NO;
} else if (self.tabBarController.selectedIndex==adType_Occasions) {
.
.
And so on...
This way, I only need to change in the storyboard and code level will not have any changes.
Is there way where I can achieve this?
Main Issue
As client ask to change tab bar completely, I need to make changes of selectedIndex changes at all places which I don't like and feel more in-efficient way. So I was looking for a way where I will make change in storyboard only and coding level there won't be any change.
The main issue for me is changing selectedIndex in all files which make more error.
I think I understand the question to mean that the code is full of number literals, referring to the selected index of the tabbar, and the business requirements about the ordering of items are shifting. Fix by changing the literals to something symbolic that can be controlled centrally:
// in a new file, indexes.h
#define INDEXA (0)
#define INDEXB (1)
#define INDEXC (2)
// wherever existing code refers to the tab selection
#import "indexes.h"
// in the code, for example if selectedIndex == 2, change to
if (self.tabBarController.selectedIndex==INDEXC) {
// ...

Disable autosuggest

My textfield name is searchtextfeild.
When I type anything, it autosuggests as in the given picture.
Now, I simply do not want to show this autosuggest. I want to disable it.
I tried,
searchtextfeild.autoautocorrectionType = FALSE;
Strange thing is though searchtextfeild is textfield, it does not have property autoautocorrectionType.
Anyway, how can I disable this autosuggest?
autocorrectionType property has type UITextAutocorrectionType which is enum:
typedef NS_ENUM(NSInteger, UITextAutocorrectionType) {
UITextAutocorrectionTypeDefault,
UITextAutocorrectionTypeNo,
UITextAutocorrectionTypeYes,
};
So you just need to do
searchtextfeild.autocorrectionType = UITextAutocorrectionTypeNo;
Check this please:
searchtextfeild.autocorrectionType = TRUE;
For some strange reason it works for me.

Dynamically setting passwordMask in Titanium

Since Titanium doesn't allow you to manually change the hintText colour of a textfield, I have to set hintText manually. Because of this, I have to dynamically change the passwordMask setting on one of fields I'm using.
However, I'm getting weird behaviour and I can't tell if I'm doing something wrong, or if it's a bug in Titanium.
So, here's my markup:
<TextField id="password" onFocus="passwordFocusEvent" onReturn="passwordReturnEvent" onBlur="passwordBlurEvent" value="password"></TextField>
And some of my controller code:
function passwordFocusEvent(e) {
slideViewUp();
if (e.value === 'password') {
e.source.setPasswordMask(true);
e.source.value = '';
}
}
function passwordBlurEvent(e) {
if (!e.value) {
e.source.setPasswordMask(false);
e.source.value = 'password';
}
}
function passwordReturnEvent(e) {
slideViewDown();
passwordBlurEvent(e);
}
What happens is bizarre. When I focus on the password field, it remains plain text. I enter some text, then click off to another field, stays as plain text.
I click back to the password field, it's STILL plain text.
Now here's the weirdness. Up to this point, I would just assume it's not working. However, when I click off this second time, the passwordMask is set.
Major WTF.
I even tried targeting the field directly using $.password.passwordMask = true; but same thing.
Unfortunately, you cant do this. According to the docs on Ti.UI.TextField in the fine print;
Note: on iOS, passwordMask must be specified when this text field is created.
Its not all bad news though, there are a couple ways you can approach this, one option is to make the password mask yourself, by listening to the change event:
var theStoredPassword = '';
$.password.addEventListener('change', function(e) {
var newpass = e.source.value;
if(newpass.length < theStoredPassword.length) {
// Character deleted from end
theStoredPassword = theStoredPassword.substring(0, theStoredPassword.length-1);
} else {
// Character added to end
theStoredPassword += newpass.substring(newpass.length-1);
}
// Mask the text with unicode ● BLACK CIRCLE, 25CF
$.password.value = new Array(newpass.length + 1).join('●');
});
Another option, would be to have two text fields and swap them out whenever the user focuses the password field, the top one would have the custom hinttext, the bottom one would be passwordMasked. In fact thats probably way easier than what I just coded up. :-)

Using a simulated event BecomeViewTarget to make an isometric camera

I'm following a tutorial on making a top down/isometric camera and have run into a bit of a snag. See, the following comes up when I compile.
BGCGamePawn.uc(15) : Error, Type mismatch in '='
Now, I've managed to get this far so I understand that the problem lies in the following bit of code. Line 15 is bold.
//override to make player mesh visible by default
simulated event BecomeViewTarget( PlayerController PC )
{
local UTPlayerController UTPC;
Super.BecomeViewTarget(PC);
if (LocalPlayer(PC.Player) != None)
{
**UTPC = BGCGamePlayerController (PC);**
if (UTPC != None)
{
//set player ctrl to behind view and make mesh visible
UTPC.SetBehindView(true);
SetMeshVisibility(True);
UTPC.bNoCrosshair = true;
}
}
}
Does BGCGamePlayerController extend from UTPlayerController? If not, that would be the problem: you're trying to cast your PlayerController parameter into a BGCGamePlayerController but then store it in a local UTPlayerController variable. You'll need to change the type for your local variable or change the hierarchy for your BGCGamePlayerController.