Delphi iOS和平移手势 - 距离始终为零

时间:2013-07-28 11:30:04

标签: ios delphi firemonkey pan

我有这个(现在正在工作)代码,基于我选择不同地方的位:

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上启用了pan + zoom geatures。

2 个答案:

答案 0 :(得分:1)

我怀疑你在各个地方获得的代码确实有效:

documentation on TGestureInfo明确指出

  

[...] 仅为缩放和两个手指点按手势设置 (TInteractiveGesture = igZoom或igTwoFingerTap)。 [...]

这意味着你必须跟踪手指在onGesture的上一次调用中注册的位置。然后,您可以对EventInfo.Location当时与EventInfo.Location的差异采取相应措施。当然,如果gfBegin不在GestureEvent.Flags中,这只会有效,因为您之前的位置没有有效值,但您已经知道了。

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

此外,如果您正在处理手势(无论是交互式还是标准手势),您都应将Handled设置为True。这样,您不会冒险尝试处理手势的其他组件。但说实话,我不确定FireMonkey是否也是如此。有了Vcl,它就是。将FMX.Types.TInteractiveGestures的文档与Vcl.Controls.TInteractiveGestureOption进行比较。比抱歉更安全。

答案 1 :(得分:0)

您好我一直在开发带滚动条的自定义fmx列表框。我发现在Windows和ios之间处理pan交互式手势事件的方式不同。在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;

我希望这很有用