Waiting for user to press a button in Swift 2 - ios

In one function in my Swift code, I need to wait until user presses a button. Otherwise, I just do nothing. How do I do this? Maybe button press triggers some event I can catch.
P.S. Due to structure of my code, doing what I want on this button press (like #IBAction) is not an option!

Declare a global boolean value such as var buttonPressed = false and then, in the IBAction of the button (When you click it):
if buttonPressed = false{
buttonPressed = true
}
And in the method you want to call when the button is pressed, just ask if buttonPressed is true.
Try that and tell me if it worked

You can set the user interaction to false by default of your main UIView (usually the UIViewController view)
self.view.userInteractionEnabled = false
and when you have the action of button you set the user interaction to true.
self.view.userInteractionEnabled = true

I might be too late but personally, there are two way you can achieve this.
Add Observer
Use delegate pattern so whenever user tap a button you notify your delegate

Related

Touch Up Inside not working properly

I have an app with some buttons, when those buttons are pressed the image on them should change. I assume that the TouchUpInside runs when you tap and remove the finger while still holding inside the area of the element, however it only works rarely and I'm not sure why.
The reason I use TouchUpInside instead of TouchDown is because I want the user to be able to cancel the action.
I'm sorry if I've misunderstood anything about those events and if this has already been asked. I couldn't find an answer to my problem searching the web.
//The IBAction is set to trigger on TouchUpInside
#IBAction func action11(sender: UIButton) {
setTile(sender)
}
func setTile(sender: UIButton) {
if turn {
print("O's turn")
sender.setImage(xTile, forState: .Normal)
turn = false
}
}
EDIT: Added the necessary code
There are some properties of UIButtons which you can use to achieve what you want.
You can use Default and selected state of uibutton to set two different images.
In XIB select state "Default" and assign default image to that state again select state to "Selected" and assign image which you want after button section.
and add following line in button selection method.
-(IBAction)buttonTapped:(UIButton *)sender{
sender.selected = !sender.selected;
}
Your understanding is correct, you need to use touchUpInside.
I assume you are trying to create a button that has a toggle function. On one touch you want the button to have the value Say "X" and when touched again the button has a value "O".
Take a look at this code below, this should do the job.
class ViewController: UIViewController {
var isButtonPressed = false{
// Adding a Property Observer, that reacts to changes in button state
didSet{
if isButtonPressed{
// Set the Value to X.
}else{
// Set the Value to O.
}
}
}
#IBAction func changeButtonValue(sender: UIButton) {
// Toggle the button value.
isButtonPressed = !isButtonPressed
}
}
If you don't set turn=true after the first time, this code is executed it will be executed only one.
if turn {
print("O's turn")
sender.setImage(xTile, forState: .Normal)
turn = false
}
Check if the button frame is large enough to get finger touch.
Apple says at least 35x35 pixel.

Adding gesture to UITextView cancels default behavior

I wanted to add a single tap gesture to a UITextView so that when my save dialog is opened I can cancel it by tapping the UITextView. However when I do that it cancels the normal single tap behavior of the textview. Now when I single tap on the text without the save drawer out it does nothing. The tap does trigger with the callback method correctly but it cancels the default action of the UITextView, (to place the cursor wherever you tapped).
// Add gesture to cancel saving
let singleCodeTextViewTap = UITapGestureRecognizer(target: self, action: Selector("codeTextViewTapped"))
singleCodeTextViewTap.numberOfTapsRequired = 1;
codeTextView.addGestureRecognizer(singleCodeTextViewTap)
func codeTextViewTapped() {
if saveDrawerOut {
moveFilenameBannerOffScreen()
saveAsTextField.text = ""
}
}
How can I enable the default behavior of the UITextView while having a single tap gesture?
EDIT
I tried adding cancelsTouchesInView = false and that does not seem to work although it would seem like the correct answer. So now my code looks like this:
singleCodeTextViewTap = UITapGestureRecognizer(target: self, action: Selector("codeTextViewTapped"))
singleCodeTextViewTap.numberOfTapsRequired = 1
singleCodeTextViewTap.cancelsTouchesInView = false
codeTextView.addGestureRecognizer(singleCodeTextViewTap)
Set the delegate of singleCodeTextViewTap to your view controller, implement gestureRecognizerShouldBegin: and return false if saveDrawerOut is true.
You could also set the cancelsTouchesInView to false. So it would be
singleCodeTextViewTap.cancelsTouchesInView = false
This would allow the gesture to be recognized and forwarded to your UITextView
Try singleCodeTextViewTap.cancelsTouchesInView = false
It should let multiple gesture recognizers live in harmony with each other.

Check if one method has been run in a different method

I'm writing some code in Xcode for an iPhone app and I want to be able to detect if a method has been run (i.e. a button was pressed, causing that method to run) in another method (I want to use an if statement so that if the button was pressed it will do this, but if it wasn't then it will do something else).
There is no has_method_been_run() function but you can check to see if the state was changed.
For example say method button_clicked() calls method change_font_to_blue(). In this case you can check to see if the font is blue and there for the method was called.
That's a very basic example of course but you could check any number of variables / the state of the UI to see if it was changed.
OR you can add a boolean to an object and just set it to true when you execute you're method that you're watching.
If your example is simply a button press I would change the UIButton's selected state
- (IBAction)buttonSelected:(UIButton *)sender {
sender.selected = YES;
// OR:
// self.myButton.selected = YES;
}
- (void)otherMethod {
if (self.myButton.isSelected) {
// button has been run through the selector method
// if you want, reset button's selected state
self.myButton.selected = NO;
} else {
// button has NOT been run through the selector method
}
}
This is a simple idea and by default the selected state of a UIButton is not visually different. If you want it to be visually changed then you can simply go into IB and change the visuals there for the selected state (including the title):
Then when the button is set to selected (self.myButton.selected = YES;) it will automatically change what the button looks like!

UIAutomation : Cancel button on Alert view is tapped without actually doing it

I'm facing this weird problem in UIAutomation.
I am checking an alert. In that, I am trying to log alert title and alert message. My code for this is:
UIATarget.onAlert = function onAlert(alert) {
UIALogger.logMessage("alert Shown");
UIALogger.logMessage(frontApp.alert().name());
UIALogger.logMessage(frontApp.alert().staticTexts()[1].value());
}
var target = UIATarget.localTarget().frontMostApp().mainWindow();
target.scrollViews()[0].buttons()["saveB"].tap();
UIATarget.localTarget().delay(2);
I am not tapping on cancel button in the alert to dismiss it. But, it is getting tapped automatically. I don't know why. Even in the logMessages, I see
target.frontMostApp().alert().cancelButton().tap()
this line getting executed automatically. I don't have this line anywhere in my script file. Is it a bug in iOS?
The cancel button on an alert is always tapped to keep the application from blocking unless the onAlert callback returns true. By returning true, you are telling the alert handling mechanism that you will handle tapping the appropriate button to dismiss the alert.
Change your alert callback to look like this:
UIATarget.onAlert = function onAlert(alert) {
UIALogger.logMessage("alert Shown");
UIALogger.logMessage(frontApp.alert().name());
UIALogger.logMessage(frontApp.alert().staticTexts()[1].value());
return true; // <-- Adding this line
}
Conversely, returning false or leaving out a return value altogether signals to the alert handling mechanism that the cancel button should be tapped.

iOS: How to prevent multiple taps of button from creating multiple new instances

Just noticed something peculiar with my app. Whenever I tap one of the bar buttons to open a popover viewcontroller, if I tap it again it simply opens another instance of that vc (I can keep doing this).
How do I stop this? Should I use a boolean to disable the button when the boolean is active and then somehow reset it when the user closes the VC by other means (such as tapping part of the screen that isn't the same VC)?
Tried the boolean suggestion:
In my prepareForSegue method I have the following:
if(isActive==false){
InformationViewController *informationViewController = [segue destinationViewController];
informationViewController.delegate = self;
isActive = true;
}
This may no longer be important, but I would recommend the boolean solution you proposed with one modification. If you move the
isActive = true;
statement to viewWillAppear, I'm pretty sure the button will remain disabled until the modal view closes.
Yes, I would suggest using a global bool value. Set the variable to true when the button is pressed.
In the function that creates the instance, check to make sure that the variable is false before creating the instance.
Once the instance is deleted, set the variable back to false.
Psuedo-code (in C++):
bool isActive = false;
void CreateInstance()
{
if (isActive == false)
{
-- code
isActive = true;
}
}
void InstanceDestroyed()
{
-- code
isActive = false;
}
You could set the button to disable once the view appears, and then add code in your popover view to:
a) send a notification using Notification Center once the popover is dismissed to be "caught" by the view that holds the button and re-enable the button, or...
b) use the delegation pattern using a protocol to handle the re-enabling of the button once the popover view is dismissed.
These methods might require a little bit more work, but I try not to use any global variables in a MVC pattern.

Resources