Delphi iOS and gesture gesture - distance is always zero

I have this bit-based (now working) code that I selected in different places:

procedure TFormMain.imgMapsGesture(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean); var LObj: IControl; LImage: TImage; W: Single; H: Single; begin LImage := nil; LObj := Self.ObjectAtPoint(ClientToScreen(EventInfo.Location)); if (LObj is TImage) and (LObj.Visible) then begin LImage := TImage(LObj.GetObject); if (LImage <> imgMaps) then LImage := nil ; end ; if LImage = nil then Exit ; if LImage.Bitmap = nil then Exit ; case EventInfo.GestureID of igiZoom: begin if (EventInfo.Distance < 1) then Exit ; if (not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags)) and (not(TInteractiveGestureFlag.gfEnd in EventInfo.Flags)) then begin W := LImage.Width + 2 * ((EventInfo.Distance - FLastDistanceZoom) / 3); H := LImage.Height + 2 * ((EventInfo.Distance - FLastDistanceZoom) / 3); if (W < layoutMapsContent.Width) or (H < layoutMapsContent.Height) then begin W := layoutMapsContent.Width; H := layoutMapsContent.Height; end ; LImage.Width := W; LImage.Height := H; FLastDistanceZoom := EventInfo.Distance; end ; end ; igiPan: begin if (not(TInteractiveGestureFlag.gfEnd in EventInfo.Flags)) then begin if (not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags)) then begin LImage.Position.X := LImage.Position.X + (EventInfo.Location.X - FMapsLastPositionPan.X); LImage.Position.Y := LImage.Position.Y + (EventInfo.Location.Y - FMapsLastPositionPan.Y); end ; FMapsLastPositionPan.X := EventInfo.Location.X; FMapsLastPositionPan.Y := EventInfo.Location.Y; end ; end ; 

I got a zoom that works quite well (not in the simulator, but on the iPhone iOS), but panning doesn't work at all. When panning in the simulator, I see that eventdisance is always 0. I turned on the pan and zoom geometry in TImage.

+2
source share
2 answers

I doubt that the code you selected in different places really works:

The documentation at TGestureInfo clearly states that

[...] The distance is set only for magnification and two finger gestures (TInteractiveGesture = igZoom or igTwoFingerTap). [...]

This means that you will need to track the position in which the finger was registered in the previous onGesture call. Then you can do something regarding the difference EventInfo.Location and then EventInfo.Location . Of course, this will work if gfBegin not in GestureEvent.Flags , because you will not have a valid value for the previous position, but you already know that.

Alternatively, you can take a look at EventInfo.InertiaVector as "the material keeps moving a little when you lift your finger." But this is completely optional.

In addition, if you control the gesture (regardless of the interactive or standard gestures), you must set Handled to True . This way, you do not risk another component trying to deal with the gesture. But to be honest, I'm not entirely sure that this also applies to FireMonkey. With Vcl, this is so. Compare the FMX.Types.TInteractiveGestures documentation with Vcl.Controls.TInteractiveGestureOption . Better than sorry.

+1
source

Hi, I am developing a custom fmx list with a scroll bar. I found that the interactive pan gesture event is handled differently between windows and ios. In the ios flag, TInteractiveGestureFlag.gfInertia is not set for an inertia event; the absence of the gfBegin and gfEnd flags indicates an inertia event.

fvscroll is a standard scrollbar component.

scmfx, scmfy - private class variables TopItem sets the top of my custom list ItemHeight is the height of the list item.

 procedure TFCListBox.FlickScroll(const Ev: TGestureEventInfo); var N:TDateTime; dy,dx,dz,rad:single; begin if TInteractiveGestureFlag.gfBegin in ev.flags then begin PanStartTime := N; PanStartEv := Ev; scrollstart := fvscroll.value; rad := DegToRad(RotationAngle); scmfx := sin(rad); scmfy := cos(rad); end; if (TInteractiveGestureFlag.gfInertia in ev.Flags) or (ev.Flags = []) then begin dy := (Ev.Location.Y - PanStartEv.Location.y) *scmfy; dx := (Ev.Location.X - PanStartEv.Location.X) *scmfx; dz := dx - dy; fvscroll.Value := scrollstart + dz; end; if TInteractiveGestureFlag.gfEnd in ev.Flags then begin TopItem := Round(fvScroll.Value/ItemHeight);} end; end; 

I hope this is helpful

0
source

Source: https://habr.com/ru/post/949609/


All Articles