Jump to content
AlexandrN

GestureRecognizer crushed after shouldBegin.

Recommended Posts

Hello, everyone! English is not my first language, so please be kind to my mistakes ... but I'll try explain my problem.

In my app need intercept swipe gesture. I read links in Apple Dev portal, more read codes on swift and objective-c different people on stackoverflow portal, and finally read delphi codes and delphi sources in RAD Studio ... But a week of torment has passed and nothing comes of it. 

Please tell me what is the problem?

My code worked, but crashed after Result := True in shouldBegin function! I not understand why? What is it magic? If something like that is in the source code of the RAD Studio, why my app receive Access violation? I think problem in this line code: 

FSwipeRecognizer.initWithTarget(GetObjectID, sel_getUid('HandleSwipe:'));

I guess because my app or system not see procedure HandleSwipe.

 

My full code:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, iOSapi.Foundation,
  iosapi.UIKit, iOSapi.CocoaTypes, FMX.Platform.iOS, Macapi.ObjCRuntime,
  Macapi.ObjectiveC, iOSapi.CoreGraphics, FMX.Helpers.iOS, iOSapi.WebKit,
  FMX.WebBrowser, Macapi.Helpers, FMX.Gestures, FMX.VirtualKeyboard.iOS;

type

  TDelegateTouch = class;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FSGRDelegate: TDelegateTouch;
  public
    { Public declarations }
  end;

  TDelegateTouch = class(TOCLocal, UIGestureRecognizerDelegate)
  private
    FSwipeRecognizer: UISwipeGestureRecognizer;
    constructor Create;
  public
    { UIGestureRecognizerDelegate }
    destructor Destroy;
    procedure HandleSwipe(gestureRecognizer: UISwipeGestureRecognizer);
    function gestureRecognizer(gestureRecognizer: UIGestureRecognizer; shouldReceiveTouch: UITouch): Boolean; overload; cdecl;
    function gestureRecognizer(gestureRecognizer: UIGestureRecognizer; shouldRecognizeSimultaneouslyWithGestureRecognizer: UIGestureRecognizer): Boolean; overload; cdecl;
    function gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer): Boolean; overload; cdecl;

  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FSGRDelegate := TDelegateTouch.Create;
end;

{ TDelegateSwipeTouch }

constructor TDelegateTouch.Create;
var UI: UIView;
    SGR: UISwipeGestureRecognizer;
    UIGest: Pointer;
    Int: Integer;
    ViewClass, FM1, FM2: Pointer;
begin
  inherited;
  FSwipeRecognizer := TUISwipeGestureRecognizer.Alloc;
  FSwipeRecognizer.initWithTarget(GetObjectID, sel_getUid('HandleSwipe:'));
  //FSwipeRecognizer.setDelaysTouchesBegan(False);
  //FSwipeRecognizer.setCancelsTouchesInView(True);
  FSwipeRecognizer.setDirection(UISwipeGestureRecognizerDirectionLeft);

  UI := WindowHandleToPlatform(Form1.Handle).View;
  UI.addGestureRecognizer(FSwipeRecognizer);
  //UI.setMultipleTouchEnabled(True);
end;

function TDelegateTouch.gestureRecognizer(
  gestureRecognizer: UIGestureRecognizer; shouldReceiveTouch: UITouch): Boolean;
begin
  Result := gestureRecognizer.isKindOfClass(objc_getClass('UISwipeGestureRecognizer'));
end;

destructor TDelegateTouch.Destroy;
begin
  FSwipeRecognizer.release;
  inherited;
end;

function TDelegateTouch.gestureRecognizer(gestureRecognizer,
  shouldRecognizeSimultaneouslyWithGestureRecognizer: UIGestureRecognizer): Boolean;
begin
  Result := NSObjectToID(shouldRecognizeSimultaneouslyWithGestureRecognizer.view) = NSObjectToID(gestureRecognizer.view);
end;

function TDelegateTouch.gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer): Boolean;
var RecognizerClassName: MarshaledAString;
begin
  RecognizerClassName := class_getName(object_getClass(NSObjectToId(gestureRecognizer)));
  Result := RecognizerClassName = 'UISwipeGestureRecognizer';
end;

procedure TDelegateTouch.HandleSwipe(gestureRecognizer: UISwipeGestureRecognizer);
begin
  //if gestureRecognizer.state = UIGestureRecognizerStateEnded then begin
    ShowMessage('Test');
  //end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FSGRDelegate.Free;
end;

end.

P.S. Part of the code was taken from the FMX.Platfom.iOS module. 

My equipment iPhone 11 iOS 14.5, MacBook Pro 13 Big Sur 11.2.3 with XCode 12.5, RAD Studio 10.4.2.

 

Thanks everyone for the answers. 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×