How can I check if a button is pressed during a specific time interval in iOS? - ios

I'm creating a game for iOS and need some help.
Simply put, random letters will be shown in a label(changing at regular interval), and the user must press the button when they recognise a pattern. If they press the button they earn points, and if they miss it, they lose points.
For example:
let's say they are looking for a letter repeating over one gap. They see the letters "R K W K". On the second K they would press the button. I need to be able to check if the button was pressed while that second K was displayed. I have searched here on stack overflow, but I can't really find anything specific to my situation. Thanks in advance for your responses. I'm new here, so I tried to be as specific as possible.

You can do something like this:
Make a global variable of type bool lets call it isMatch.
While displaying other letters make isMatch = false;
When you display the second 'K' (as your example) make isMatch = true
In you button click method check:
if(isMatch){
point++;
}
else point--;
Make sure you change isMatch = false on displaying other letters.
Hope this helps.. :)

As I understood you are displaying K (say) in UILabel and you might be getting input in UITextField, what you should do is implement ValueChanged IBAction for UITextField and add all letters (K, M, X, H) etc in an array what you have on screen for now. When the text changes it will come in above IBAction, match the UITextField's text with the elements of an array. If there is a match, you are done!
Hope this helps!

Just check in the selector for the button ... (If you're using Interface builder replace void with IBAction)
- (void) buttonWasPressed:(UIButton *) sender {
if ([[[sender titleLabel] text] isEqualToString:#"K"])
point ++;
else
point --;
}

try like this
- (void)buttonTapped:(UIButton *)yourbutton;
{
yourbutton.selected = ![yourbutton isSelected];
}
then this
[self.yourbutton isSelected];

Related

Swift 2: Call a method after pressing Return in UITextField

I have a Text Field in a Tip Calculator. I want the Tip Calculator to update all the fields of my calculator.
With the current code that I have now, for whatever reason. It doesn't call calcTip() (or atleast it doesn't seem to) until I press return once, enter another (or the same) value and press return again.
I'm really close to having this app work exactly how I want it to, and I feel like I'm just 1 or 2 lines away.
My ViewController conforms to UITextFieldDelegate, and I declared amountBeforeTaxTextField.delegate = self in viewDidLoad.
TextShouldReturn:
func textFieldShouldReturn(textField: UITextField) -> Bool {
amountBeforeTaxTextField.clearsOnBeginEditing = true
amountBeforeTaxTextField.becomeFirstResponder()
calcTip()
amountBeforeTaxTextField.resignFirstResponder()
return true
}
calcTip():
func calcTip() {
let tip = tipCalc.calculateTip()
let total = tipCalc.calculateTotal()
let tax = tipCalc.calculateTax()
let perPerson = total / Float(Int(partySizeSlider.value))
tipCalc.tipPercentage = (tipPercentageSlider.value)
tipCalc.amountBeforeTax = (amountBeforeTaxTextField.text! as
NSString).floatValue
tipCalc.taxPercentage = (taxPercentageSlider.value)
resultLabel.text = String(format: "Tip $%.2f, Tax: $%.2f Total: $%.2f", tip, tax, total)
perPersonLabel.text = String(format: "Per-Person Total: $%.2f", perPerson)
}
Note: I have the same outcome with & without .becomeFirstResponder()
Thanks for reading.
So your textFieldShouldReturn function is called when you press the bottom right button on the keyboard, which can have various titles; such as "Go", "Return", "Done", or "Send".
Your first line, only accomplishes a UI effect; meaning when the user taps on the textfield to input text, there will be a little box that appears on the far right handside of the textfield that allows the user to clear the inputted text, if there is any. Sort of like a reset.
When you use becomeFirstResponder, you are pretty much calling another keyboard to pop up, so you aren't accomplishing anything by doing that.
When you use resignFirstResponder, you are hiding the keyboard.
What you want to do is remove "becomeFirstResponder" as well as the first line, because those don't do anything to help your problem. That should be the solution to the problem you are facing.

How to get index of XCUIElement in XCUIElementQuery?

This is my simple UITest (customizing order of tabs in tabbarcontroller):
func testIsOrderOfTabsSaved() {
let app = XCUIApplication()
let tabBarsQuery = app.tabBars
tabBarsQuery.buttons["More"].tap()
app.navigationBars["More"].buttons["Edit"].tap()
tabBarsQuery.buttons["Takeaway"].swipeLeft()
tabBarsQuery.buttons["In Restaurant"].swipeLeft()
//here, how to get position of moved button with text "In Restaurant"?
NOTE:
It is possible to get XCUIElement from XCUIElementQuery by index. Can I do this fro the other way?
It seems that the queries automatically return in order based on position on screen.
for i in 0...tabsQuery.buttons.count {
let ele = tabsQuery.buttons.elementBoundByIndex(i)
}
Where the index i represents the position of the button in the tab bar, 0 being the leftmost tab, i == tabsQuery.buttons.count being the rightmost.
You have various ways to create a position test. The simplest way is to get buttons at indices 0 and 1, then get two buttons by name and compare the arrays are equal: (written without testing)
let buttonOrder = [tabBarsQuery.buttons.elementAtIndex(0), tabBarsQuery.buttons.elementAtIndex(1)]
let takeawayButton = buttons["Takeaway"];
let restaurantButton = buttons["In Restaurant"];
XCTAssert(buttonOrder == [takeawayButton, restaurantButton])
Another option is to directly get the frame of each button and assert that one X coordinate is lower than the other.
To answer your specific question about getting the index of an XCUIElement in a XCUIElementQuery, that's absolutely possible. Just go through all the elements in the query and return the index of the first one equal to the element.
An XCUIElement alone isn't able to tell you its position in within the XCUIElementQuery. You can search the XCUIElementQuery to discover its offset if you know something about the XCUIElement. In the below let's imagine that "More" is the identifier (change 'identifier' to 'label' if that is what you're working with).
If you want to find the offset of the "More" button (as posted in the original question) then:
var offsetWithinQuery : Int? = nil // optional since it's possible the button isn't found.
for i in 0...tapBarsQuery.buttons.count{
if tapBarsQuery.elementAtIndex(i).indentifier == "More" {
offSetWithinQuery = i
}
After the above loop exits, you'll either have the offset or it'll be nil if "More" isn't found.

UITextField input every time new iteration

I'm new to Objective-C and Xcode, and I have one problem, I tried looking in the Internet, but didn't find anything.
I have "game" and there I have a screen with two text fields, button and text view.User inputs integer values and taps the button. After tapping the button some functions(or, methods) are called. Method that is called after typing the button:
- (IBAction)okButtonTapped:(id)sender {
int save1=100;
int save2=100;
int save13=1;
int save22=1;
int save12=1;
int save23=1;
while(save13 !=0 && save23 !=0){
[self yourturn:&save1 heap2:&save2];
save12= save1;
save22=save2;
[self compturn:&save12 heap2:&save22];
save13=save12;
save23=save22;
save1=save13;
save2=save23;
}
}
Here some methods are called. And in this methods I use this code to save values from textfields that user inputs:
_heapNumberInt=[self.heapNumberTextField.text intValue];
_thingsNumberInt=[self.thingsNumberTextField.text intValue];
And the question is how to make users input new values in the textfield every time when there is new iteration in while loop?
Sorry for my English(it's not my native language) and for my long question.
All project you can download here
P.S. "game" is very simple: there are 2 heaps with 100 things each, user chooses his turn and then he inputs values: heap number(1 or 2 heap) and number of things he wants to take from the heap. Then there is computer's turn. And looser is someone who can't take things from any heap. It is real game called NIM.(but here I made only 2 heaps(not 3)).
Probably you need to read Event Handling Guide
https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009541
About the question, for setting focus to the input you should use
[self.heapNumberTextField becomeFirstResponder];
UPDATE:
As I understand you need to:
_heapNumberInt = [self.heapNumberTextField.text intValue]; // get value
[self.heapNumberTextField setEditable:NO]; // disable editing to calculate
[self calculate];
self.heapNumberTextField.text = #""; // clean UITextField
[self.heapNumberTextField setEditable:YES]; // allow editing
[self.heapNumberTextField becomeFirstResponder]; // set focus to the textfield

UILabel text changing between two strings with each "touch up inside"

I'm learning OBJ.C/Xcode/Cocoa here and have run into a question I can't seem to find an answer for.
I want the text in a UILabel to switch between two states (ON/OFF for example) each time the user clicks the same button.
I can get the label to switch to one state, but can't get it to switch "back" when the user clicks the button again. I am assuming there is some logic required, or checking the status of the object once the button is clicked...
Does this require me to keep track of a bool or the "state" of the Label (or button)?
Would this require two methods to be associated to the button, or can it happen with just one?
Thanks for any guidance/pointing in the right direction/Code snips!!!!
~Steve
I got an answer, and it works:
- (IBAction)flip:(id)sender
{
_flipButton.selected = !_flipButton.selected;
self.flipLabel.text = (_flipButton.selected) ? #"ON" : #"OFF";
}
- (IBAction)flip:(id)sender {
[yourButton setSelected:!yourButton.selected];
self.flipLabel.text = (yourButton.selected) ? #"ON" : #"OFF";
}
This toggles the selected state of the button then checks its state to determine which string to pass to the text property of your label.
the easiest way (I think) is to store a BOOL with the state of the UILabel and (on each click of the button) negate the BOOL and set the appropriate text of the Label
You could call this: yourLabel.enabled = !yourLabel.enabled on button click to change the enabled-state of your UILabel. Or what kind of state do you mean ?

Best method to determine the sender of an event

I have a simple question about event handling in iOS applications... suppose you have an app with some buttons that react to the TouchUpInside event calling the same action, what is the best way within the action method to understand what is the button that triggered the event? I know that it can be easily done using the title of the button, but I think it is not the best way if you have a localized app in which button text may change (unless it is possible to reverse the localization of the title, i.e. retrieve the original string from a localized string)... is there a good practice about this topic? Should I use some other property of buttons to distinguish among different buttons?
Thank you in advance for any help.
There is something called a "Tag" that you can set for UIButtons, or anything that can respond to an event for that matter. If you are using Interface Builder, click the attributes inspector for the item and select a value for the tag (integer). In your code do something like this...
...
- (IBAction)buttonReceived:(id)sender
{
if ([sender tag] == 1) {
//Do something
}
else if ([sender tag] == 2) {
//Do something else
}
}
In addition to the tag property, or just in case you are already using the tag for some other purpose that would mean duplicate tag values for one or more different buttons, you can always set up an IBOutlet ivar to each button you needed to check, and then in the IBAction, do something like this:
- (IBAction)buttonReceived:(UIButton *)sender
{
if (sender == myButtonA) {
// processing for button A
}
else if (sender == myButtonB) {
// processing for button B
}
}
It is a bit more work, but it can come in handy at times.

Resources