我有这个(现在正在工作)代码,基于我选择不同地方的位:
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。
答案 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;
我希望这很有用