簡體   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