3

我有这个(现在工作的)代码,基于我在各个地方找到的位:

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
;

我的缩放工作得很好(不是在模拟器中,而是在 iOS iPhone 上),但是平移根本不起作用。在模拟器中平移时,我可以看到 eventdisance 始终为 0。我在 TImage 上启用了平移 + 缩放功能。

4

2 回答 2

1

我怀疑您在各个地方获取的代码是否真的有效:

TGestureInfo 上的文档明确指出

[...] 距离仅针对缩放和两个手指点击手势(TInteractiveGesture = igZoom 或 igTwoFingerTap)设置。[...]

这意味着您必须跟踪手指在上一次调用中注册的位置onGestureEventInfo.Location然后,您可以针对当时和EventInfo.Location现在的差异做一些事情。当然,这只有在不在的情况下才有效gfBeginGestureEvent.Flags因为您不会获得先前位置的有效值,但您已经知道这一点。

此外,您可能会查看EventInfo.InertiaVector“当您抬起手指时,东西会继续移动一点”。但这完全是可选的。

此外,如果您正在处理手势(无论是交互式手势还是标准手势),您应该设置HandledTrue. 这样,您就不会冒另一个组件尝试处理该手势的风险。但老实说,我不确定 FireMonkey 是否也是这种情况。使用 Vcl,它是。将FMX.Types.TInteractiveGestures的文档与Vcl.Controls.TInteractiveGestureOption进行比较。安全总比后悔好。

于 2013-07-28T20:50:06.597 回答
0

您好我一直在开发一个带有滚动条的自定义 fmx 列表框。我发现平移交互手势事件在 windows 和 ios 之间的处理方式不同。在 ios 中,没有为惯性事件设置 TInteractiveGestureFlag.gfInertia 标志,没有 gfBegin 和 gfEnd 标志表示正在发生惯性平移事件。

fvscroll 是一个标准的滚动条组件。

scmfx,scmfy 是私有类变量 TopItem 设置我的自定义列表框的顶部项 ItemHeight 是列表框项的高度

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;

我希望这是有帮助的

于 2013-08-28T11:49:13.610 回答