繁体   English   中英

使用Delphi XE5在UIView类[Swizzling]中使用Hook touchesBegan

[英]Hook touchesBegan inside UIView class [Swizzling] with Delphi XE5

我试图在全球范围内捕捉所有触摸事件。 为此,我知道我可以在UIView类中挂钩触摸事件过程。 我有编译的代码。 我实现的钩子是

procedure touchesBeganDetour(self: id; _cmd: SEL; touches: NSSet; withEvent: UIEvent); cdecl;
begin
  Sleep(1);
end;

然后我尝试用两种不同的方式挂钩。 第一:

constructor TTouchEventListener_IOS.Create;
var
  FM1, FM2: Pointer
  ViewClass: Pointer;
begin
  inherited;

  ViewClass := objc_getClass('UIView');
  class_addMethod(ViewClass, sel_getUid('touchesBeganDetour:'), @touchesBeganDetour, 'v@:@@');
  FM1 := class_getInstanceMethod(ViewClass, sel_getUid('touchesBegan:withEvent:'));
  FM2 := class_getInstanceMethod(ViewClass, sel_getUid('touchesBeganDetour:'));
  method_exchangeImplementations(FM1, FM2);
end;

这似乎是标准方法。 第二个:

constructor TTouchEventListener_IOS.Create;
var
  FM1
  ViewClass: Pointer;
begin
  inherited;

  ViewClass := objc_getClass('UIView');
  FM1 := class_getInstanceMethod(ViewClass, sel_getUid('touchesBegan:withEvent:'));
  method_setImplementation(FM1, @touchesBeganDetour);
end;

据我所知,这也应该有用。 我得到了“ touchesBegan:withEvent ”的实例,并且所有代码都执行没有错误。 但是当我接触模拟器屏幕时,代码在单元“ Macapi.ObjectiveC.pas ”中的“ DispatchToImportSuper ”内崩溃。 我显然做错了什么,但我不知道是什么。 如果这样可行,则可以在不修改Delphi源代码的情况下收听触摸事件。

有人有什么想法吗?

再次回答我自己的问题。 问题出在绕行程序声明中。 看来你不能指定原始参数,但你必须使用指针而不是接口。 这可能是由于objectiveC和object pascal之间的差异。 您稍后“换行”,从而将指针转换为正确的接口。

procedure touchesBeganDetour(self: id; _cmd: SEL; touches: Pointer; withEvent: Pointer); cdecl;
begin
  DoNotifyTouchEvent(TNSSet.Wrap(touches), TUIEvent.Wrap(withEvent), teDown);
end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM