How to Stop Single Tap From firing before Double Tap - gestures

I am trying to set a simple double tap recognition before moving to more complicated interactions. I have the single and double tap being recognised. However, my problem is that the double tap doesn't fire without the single tap.
I have seen the code which covers introducing a requirement to fail, but the sample code I do not understand how to modify to make work with my standard approach.
Here is my code - at the moment I am just trying to get the log to fire and it is. But on double tap I get the single tap message which I don't want. I have tried changing the TapGestureRecognizer event settings to no avail.
- (IBAction)didTapPhoto1:(UITapGestureRecognizer *)sender; {
NSLog(#"Did Tap Photo1 !");
}
- (IBAction)didDoubleTapPhoto1:(UITapGestureRecognizer *)sender; {
NSLog(#"DoubleTap");
}
Thank you

Use UIGestureRecognizer requireGestureRecognizerToFail: method.
[singleTapGestureRecognizer requireGestureRecognizerToFail:doubleTapGestureRecognizer].
There is a side effect of this method, if you only tap one time on the screen, it will react slower than that without calling the method.
Edit: It seems that you create the gesture recognizer in Storyboard or xib. You can also do it with code.
UITapGestureRecognizer *singleGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(didTapPhoto1:)] ;
singleGR.numberOfTapsRequired = 1 ;
UITapGestureRecognizer *doubleGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(didDoubleTapPhoto1:)] ;
doubleGR.numberOfTapsRequired = 2 ;
// you can change self.view to any view in the hierarchy.
[self.view addGestureRecognizer:singleGR] ;
[self.view addGestureRecognizer:doubleGR] ;
[singleGR requireGestureRecognizerToFail:doubleGR] ;

Related

Showing progress window while creating other window/widgets

I have a function that looks like the following
void MainWindow::CreateEnvironment()
{
MdiWindow* sub = createSubWindow();
MyQTWidget* widget = CreateWidget();
..
..
}
I want that during this function a progress bar will be shown at the beggining and will close at the end of this function.
However adding
void MainWindow::CreateEnvironment()
{
**progressBarDialog->show();**
MdiWindow* sub = createSubWindow();
MyQTWidget* widget = CreateWidget();
..
..
**progressBarDialog->hide();**
}
Does not work, maybe because the function needs to exit first or something.
What is the best way to do this?
I assume that you use QProgressDialog?
You need to first setup the dialog with the correct number of steps you expect, how long you want to wait before it actually shows and more importantly: you need to call setValue() to update the progress bar.
Here is an example of how I would solve that (as far as I understand it)
void MainWindow::CreateEnvironment()
{
auto bar = new QProgressBarDialog(this);
bar->setLabelText(tr("Creating Environment..."));
bar->setCancelButton(nullptr); // No cancel button
bar->setRange(0, 10); // Let's say you have 10 steps
bar->setMinimumDuration(100); // If it takes more than 0.1 sec -> show the dialog
bar->setValue(0);
MdiWindow* sub = createSubWindow();
bar->setValue(1);
MyQTWidget* widget = CreateWidget();
..
..
bar->setValue(10);
MyLastWidget* last = CreateLastWidget();
bar->deleteLater(); // Not needed anymore, let's get rid of it
}
And don't worry too much if the dialog never shows. Unless you're doing really heavy computation (such as allocating / initialising huge portion of memory), creating widgets is very fast and would finish before the 100ms times out.
EDIT: Another thing to be aware of: QProgressDialog is meant to work after the main event loop started. (That is after the call to app.exec() in your main())
If you plan to show call this function in the constructor of your MainWindow, the dialog might even never show up because the window itself is not fully created and operational.
If you intended to call this function later, when the main window is already displayed on screen and the user hit a New Document button of some sort: you can ignore this part of the answer.

Xamarin Forms Prism DialogService takes some seconds to show up

My Dialog is a simple Frame with an Image, a label to display a question and two more labels (Yes / No) with TapCommand.
I've set up the container with the DialogPage.xaml and DialogPageViewModel and injected in the ViewModel I want to open the dialog.
Here is the code I'm using to call the Dialog:
public void ShowDialog()
{
_dialogService.ShowDialog("DiscardPopup", CloseDialogCallback);
}
void CloseDialogCallback(IDialogResult dialogResult)
{
var goBack = dialogResult.Parameters.GetValue<bool>("GoBack");
if (goBack)
NavigationService.GoBackAsync();
}
If the user taps over the "Yes label", I execute this command:
YesCommand = new DelegateCommand(() => YesTapped());
private void YesTapped()
{
IDialogParameters pa = new DialogParameters();
pa.Add("GoBack", true);
RequestClose(pa);
}
If the user taps over the "No label", I simply call:
NoCommand = new DelegateCommand(() => RequestClose(null));
The "problem" is when the ShowDialog is fired, the DiscardPopup is taking up to 3 seconds to show up.
Is there a way to make it faster?
The same happens with the TapCommands, 2 - 3 seconds when the RequestClose is invoked.
Without actual code telling you exactly what the issue is, is going to be best guess. Based on your feedback to my comments above I would suggest the following:
Try displaying the dialog on a test page that doesn't have a complex layout. My guess is that you won't see such a long load time. If that's the case this would point to your layout being overly complex and that the lag time is due to the device struggling to re-render the View
Try using Prism.Plugin.Popups. You'll need to initialize Rg.Plugins.Popup and register the DialogService. You can see docs on that at http://popups.prismplugins.com

JavaFX 8: Intercepting appication "exit"

In order to verify that all changes made by the user have been saved I want to intercept the exiting/quitting of a JavaFX application.
Is there a common way-to-go to achieve this like overriding an event or is there more to it?
As they have already said, this is done by intercepting WindowEvent.WINDOW_CLOSE_REQUEST. You can then stop the suspension by calling event.consume().
This is an example of how to capture the event and display a confirmation dialog. Depending on the user's choice, you can take serialization actions if you wish.
primaryStage.setOnCloseRequest(event -> {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.initOwner(primaryStage);
alert.initModality(Modality.APPLICATION_MODAL);
alert.setHeaderText("Exit");
alert.setContentText("Do you want to exit?");
alert.getDialogPane().getButtonTypes().setAll(ButtonType.OK, ButtonType.NO);
Optional<ButtonType> optional = alert.showAndWait();
if(optional.isPresent() && optional.get() == ButtonType.OK) {
// save data
return;
}
event.consume();
});
In order for the implementation to be complete, you need to implement a logic for clear exit from the application from control. For example, when choosing from the File menu -> Close. When capturing the event, you must run WindowEvent.WINDOW_CLOSE_REQUEST to trick the exit logic.
closeMenuItem.setOnAction(event -> {
Window window = menuBar.getScene().getWindow();
window.fireEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSE_REQUEST));
});
In the class Application there is the stop method which you can override possibly.

how to make an object visible again in game maker

Fist of all, I'm really sorry for my bad English and I pretty new to game maker .
I have 2 object in the game : obj_apple and obj_door( I unchecked visible box)
my question is
how can I make an obj_door visible in the room when all the obj_apple are destroyed?
Object obj_door, Step event, place code (Add event -> Step -> Step -> tab Control -> section Code, first icon (Execute code)):
if !instance_exists(obj_apple) visible = true;
Another option, so you aren't making a check in every step event, is to put the check for the number of obj_apple in the destroy event of obj_apple.
For example, in the destroy event of obj_apple you would have:
if (instance_number(object_index) == 0) {
with (obj_door) {
visible = true;
}
}

useLayoutToLayoutNavigationTransitions in iOS7 crash

I am building an iOS7 app and I am trying to make use of the new useLayoutToLayoutNavigationTransitions effect. I have 2 UICollectionViewControllers and when I do the following I get the transition effect
SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondVC.useLayoutToLayoutNavigationTransitions = YES;
[self.navigationController pushViewController:secondVC animated:YES];
this works fine but what I want to do is make an api call and then in the completion block I want to push onto the nav stack like so
[webAPI getDetailsWithParams:params andCompletionBlock:^(id dict) {
//some work on the result
SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondVC.useLayoutToLayoutNavigationTransitions = YES;
[self.navigationController pushViewController:secondVC animated:YES];
} andErrorBlock:^(NSError *error) {
}];
but this crashes every time with the following msg
-[UICollectionView _invalidateLayoutWithContext:]: message sent to deallocated instance 0x17a26400
can anyone tell me what I am doing wrong in this case? How can I get the transition effect when pushing from completion block?
EDIT: by changing it to the following I was able to transition to the second viewcontroller.
MyLayout *layout = [[MyLayout alloc] init];
SecondViewController *expandedVC = [[SecondViewController alloc] initWithCollectionViewLayout:layout];
and I also deleted the nib file that went with the file. nib file just consisted of a collection view and it was the file owners view.
While I can now transition I still do not understand why I could not do the previous nib method with in a block. So I would be grateful if someone could shed some light on it for me.
In order to use UICollectionViewController's useLayoutToLayoutNavigationTransitions to make transitions, the layout of the SecondViewController must be known. However, if you use initWithNibName:bundle: initializer, layout is not internally prepared yet, making your desired transitions impossible. As you mentioned in your edited question, you have to use [UICollectionViewController initWithCollectionViewLayout:] to initialize your second UICollectionViewController. Since your xib file has the same name as your class name, SecondViewController.xib is going to be loaded automatically by UIViewController, superclass of UICollectionViewController.
I think you were making UIKit calls from a thread that wasn't the main thread

Resources