Hallo zusammen,
ich kämpfe jetzt seit Wochen (Monaten) mit iOS und dem LongTap GestureRecognizer.
Ich möchte einfach auf einer Fläche mit dem Finger zeichen, und das auch wenn man mal zum Anfang etwas länger
gedrückt hält.
Dazu benutze ich die MouseDown, MouseMove, MouseUp wie ich es unter Win auch machen würde.
Diese werden von TouchesBegan, TouchesMoved, TouchesCancelled und TochesEnd abgeleitet.
Es passiert aber Folgendes:
- nach ca. 0.5 Sek. wird wohl der LongTap erkannt,
dieser sorgt dafür das TouchesCancelled feuert,
das sgt dafür das MouseUp gefeuert wird,
danach ist MouseMove und der ganze Zyklus beendet, weil LongTap ein permanenter Event ist der die Maus hält
==> Resultat: Kein Tap und Draw möglich wenn man mit LongTap beginnt
- starte ich mit dem Finger und bewege mich direkt, dann ist alles so wie gewollt, LongTap kommt nie.
Ich habe jetzt schon zig Versuche gemacht diese dämliche TochesCancelled Problematik loszuwerden, ohne Erfolg.
Was jetzt geholfen hat ist etwas brutal:
- ich werfe in FMX.Platform.iOS den AddGestureRecognizer(LongTap) komplett raus.
Delphi-Quellcode:
procedure TFMXViewBase.AddRecognizer(const Gesture: TInteractiveGesture);
var
TwoFingerTapRecognizer: UITapGestureRecognizer;
RotateRecognizer: UIRotationGestureRecognizer;
ZoomRecognizer: UIPinchGestureRecognizer;
PanRecognizer: UIPanGestureRecognizer;
LongTapRecognizer: UILongPressGestureRecognizer;
begin
case Gesture of
TInteractiveGesture.Zoom:
begin
ZoomRecognizer := TUIPinchGestureRecognizer.Alloc;
ZoomRecognizer := TUIPinchGestureRecognizer.Wrap(ZoomRecognizer.initWithTarget(GetObjectID, sel_getUid('HandleZoom:')));
ZoomRecognizer.setDelaysTouchesBegan(False);
ZoomRecognizer.setCancelsTouchesInView(True);
ZoomRecognizer.setDelegate(GetObjectID);
UIView(Super).addGestureRecognizer(ZoomRecognizer);
ZoomRecognizer.release;
end;
TInteractiveGesture.Rotate:
begin
RotateRecognizer := TUIRotationGestureRecognizer.Alloc;
RotateRecognizer := TUIRotationGestureRecognizer.Wrap(RotateRecognizer.initWithTarget(GetObjectID, sel_getUid('HandleRotate:')));
RotateRecognizer.setDelaysTouchesBegan(False);
RotateRecognizer.setCancelsTouchesInView(True);
RotateRecognizer.setDelegate(GetObjectID);
UIView(Super).addGestureRecognizer(RotateRecognizer);
RotateRecognizer.release;
end;
TInteractiveGesture.Pan:
begin
PanRecognizer := TUIPanGestureRecognizer.Alloc;
PanRecognizer := TUIPanGestureRecognizer.Wrap(PanRecognizer.initWithTarget(GetObjectID, sel_getUid('HandlePan:')));
PanRecognizer.setMinimumNumberOfTouches(1);
PanRecognizer.setMaximumNumberOfTouches(2);
PanRecognizer.setDelaysTouchesBegan(False);
PanRecognizer.setCancelsTouchesInView(False);
PanRecognizer.setDelegate(GetObjectID);
UIView(Super).addGestureRecognizer(PanRecognizer);
PanRecognizer.release;
end;
TInteractiveGesture.TwoFingerTap:
begin
TwoFingerTapRecognizer := TUITapGestureRecognizer.Alloc;
TwoFingerTapRecognizer := TUITapGestureRecognizer.Wrap(TwoFingerTapRecognizer.initWithTarget(GetObjectID, sel_getUid('HandleTwoFingerTap:')));
TwoFingerTapRecognizer.setNumberOfTapsRequired(1);
TwoFingerTapRecognizer.setNumberOfTouchesRequired(2);
TwoFingerTapRecognizer.setDelaysTouchesBegan(False);
TwoFingerTapRecognizer.setCancelsTouchesInView(True);
TwoFingerTapRecognizer.setDelegate(GetObjectID);
UIView(Super).addGestureRecognizer(TwoFingerTapRecognizer);
TwoFingerTapRecognizer.release;
end;
TInteractiveGesture.LongTap:
begin
//S4: OFF, to avoid MouseUp
//TODO: Better to remove the Recognizer only for the desired view, not globally
// LongTapRecognizer := TUILongPressGestureRecognizer.Alloc;
// LongTapRecognizer := TUILongPressGestureRecognizer.Wrap(LongTapRecognizer.initWithTarget(GetObjectID, sel_getUid('LongTap:')));
// LongTapRecognizer.setDelaysTouchesBegan(False);
// LongTapRecognizer.setCancelsTouchesInView(True);
// LongTapRecognizer.setDelegate(GetObjectID);
// UIView(Super).addGestureRecognizer(LongTapRecognizer);
// LongTapRecognizer.release;
end;
end;
end;
Das funktioniert zum Glück, auch weil ich sonst nirgendwo den LongTap benötige.
Aber das kann ja wohl nicht im Sinne des Erfinders sein, ich habe noch andere Ideen, wie
- der Form mit RemoveRecognizer den Handler wieder entziehen (ging aber nicht mit dem PlatformServices)
- die LongTap Zeit separat auf 0 oder 99999 setzen (aber wo kann ich darauf zugreifen, wenn nicht global)
Hat schon jemand dieses Problem gehabt, und gibt es andere Workarounds dafür ?
Rollo