2014-02-04 1 views
3

Я пытаюсь поймать все события касания по всему миру. Для этого я знаю, что могу подключить процедуры сенсорного события в классе UIView. У меня есть код, который компилируется. Моя реализация крючкаЗахват троганийБеган в классе UIView [Swizzling] с Delphi XE5

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, '[email protected]:@@'); 
    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; 

Это должно также работать, насколько я понимаю. Я получаю экземпляр «touchhesBegan: withEvent», и весь код выполняется без ошибок. Но когда я прикасаюсь к экрану симулятора, код падает внутри «DispatchToImportSuper« в блоке »Macapi.ObjectiveC.pas». Я, очевидно, что-то делаю неправильно, но я понятия не имею. Если это сработает, это позволит прослушивать события касания без изменения исходного кода Delphi.

У кого-нибудь есть идеи?

ответ

2

Чтобы снова ответить на мой вопрос. Проблема заключалась в объявлении процедуры обхода. Кажется, вы не можете указать исходные параметры, но вам нужно использовать указатели вместо интерфейсов. Вероятно, это связано с различиями между objectC и объектом pascal. Вы позже «обертываете» и тем самым накладываете указатели на исправление интерфейсов.

procedure touchesBeganDetour(self: id; _cmd: SEL; touches: Pointer; withEvent: Pointer); cdecl; 
begin 
    DoNotifyTouchEvent(TNSSet.Wrap(touches), TUIEvent.Wrap(withEvent), teDown); 
end; 
Смежные вопросы