基于iOS控件的FireMonkey控件的行为不正确

时间:2013-07-29 08:34:46

标签: ios delphi delphi-xe4 firemonkey-fm3

我们开始将我们现有的iOS(XCode)应用程序之一移植到Delphi FireMonkey(XE4)。到目前为止,它的过程非常顺利。然而,我们已经走到了死胡同,我们不知道如何解决。

我们现有的应用与新的Google Maps应用类似。我们有一个webbrowser控件,可显示包含多个图钉的Google地图。我们还有一个设置按钮和一个信息面板,当针脚被剔除时会出现。按下相应的按钮/按钮时,设置和信息面板将从地图的左侧和右侧滑入。这一切都可以在XCode应用程序中正常工作。

以下是我们使用FireMonkey端口时遇到的问题:

  • 我们无法在Web浏览器的顶部显示FireMonkey控件 控制。我知道这是因为webbroswer是原生的 iOS控件。
  • 一旦web浏览器控件出现,就无法移动,例如要是我们 更改 position.x 属性,webbrowser保持原样。 如果我们使用内置更改为x属性,则相同 动画。唯一似乎正常工作的属性是 visible

使用TMS iCL组件,我们可以纠正第一个问题。然而,对我们来说最令人担忧的问题是第二个问题。如果无法移动webbrowser组件,则无法实现使用webbrowser(或任何本机iOS控件)的现代外观(滑动)UI。

有没有人遇到过克服这些FireMonkey限制的方法?

更新1

根据Jaroslav的建议,我尝试了以下方法:

1)使用按钮和WebBrowser创建第二个表单。

unit Unit2;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
  FMX.StdCtrls, FMX.WebBrowser;

type
  TForm2 = class(TForm)
    WebBrowser1: TWebBrowser;
    Button1: TButton;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.fmx}

end.

2)创建Form2作为Form1的子项。

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, FMX.WebBrowser,

  Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FForm2: TForm2;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Fform2.left := Fform2.left - 5;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Fform2.left := Fform2.left + 5;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FForm2 := TForm2.Create(Self);
  FForm2.Parent := Self;
  FForm2.Left := 10;
  FForm2.Show;
  FForm2.BringToFront;
  FForm2.WebBrowser1.URL := 'www.google.com';
  FForm2.WebBrowser1.Navigate;
end;

end.

当我运行应用程序时,我看到了:

enter image description here

以下是我的观察:

  • 点击按钮无效。
  • Form2上的按钮不可见。
  • Form2的Left属性在设计器中设置为40。但是,表单显示为0。

更新2:

根据评论中的建议,我将Form1源更改为:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, FMX.WebBrowser,

  Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Popup1: TPopup;
    WebBrowser1: TWebBrowser;
    WebBrowser2: TWebBrowser;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FForm2: TForm2;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
  TCustomForm(Popup1.Popupform).Left := TCustomForm(Popup1.Popupform).Left - 5;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  TCustomForm(Popup1.Popupform).Left := TCustomForm(Popup1.Popupform).Left + 5;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  WebBrowser1.URL := 'www.google.com';
  WebBrowser1.Navigate;
  Popup1.Popup(FALSE);
end;

end.

不幸的是,机芯和覆盖层都不起作用。当引用TCustomForm(Popup1.Popupform).Left时,当前代码抛出异常。发生异常的原因是,只要在父窗体上发生鼠标左键事件,Delphi就会关闭弹出窗口(销毁弹出窗体)。甚至更奇怪的是,即使它在点击时没有反应,但是在它应该关闭之后仍然可以看到带有webbrowser的弹出窗口。

将代码更改为Popup1.Position.X不会引发异常,但当然弹出窗口仍然不会移动。

此外,弹出窗口的标签仍然显示在主窗体所拥有的webbrowser下。

更新3

我发现了很多问题,但修复它们并没有让它更好用。

  1. 对于某些(莫名其妙的)原因,似乎切割控件(CTRL-X),然后选择另一个控件并粘贴(CTRL-V)将剪切控件粘贴到主窗体,而不是选定的控件。重新显示控件的唯一方法是将其拖放到Structure树中。
  2. 将控件重新显示给PopUp后,我现在只要调用Popup1.Popup(FALSE)就会出现异常。这很可能是因为弹出窗口正在Create事件中显示。将它移动到OnClick事件可以消除异常。
  3. 似乎为了在单击主窗体时停止弹出窗口关闭,您应该在调用.Popup之前设置StaysOpen属性,但实际上,此属性似乎无法正常工作。例如,以下代码使其成为TCustomForm(Popup1.PopupForm).Left行,但随后弹出窗体已被销毁,因此抛出异常!
  4. 代码:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Popup1.StaysOpen := TRUE;
      Popup1.Popup(FALSE);
    
      if Popup1.HasPopupForm then
        TCustomForm(Popup1.PopupForm).Left := TCustomForm(Popup1.PopupForm).Left - 5;
    end;
    

1 个答案:

答案 0 :(得分:2)

对于解决方案,我们应该知道:

  1. 每个Firemonkey表单都基于Native UIView ,它是Main UIViewController 中的根视图的子视图。因此,当您在FireMonkey表单上插入控件时,该控件将保留在Form的 UIView 上。
  2. 所有标准Firemonkey控件都没有Native UIView。 FMX表单具有所有FMX控件并对其进行管理。
  3. Firemonkey WebBrowser基于 UIWebView ,在Firemonkey表单的 UIView 中显示为子视图。
  4. 所有Popup表单都基于具有透明背景的UIView。弹出窗口和大小的位置通过属性TForm.Position,TForm.Size设置。因此,您可以在Form上创建一个带有透明背景的表单,其中包含TWebBrowser,设置大小和设置位置。
  5. 要解决您的问题,您可以:

    1. 创建新表单或弹出表单
    2. 设置尺寸和位置。
    3. 使用WebBrowser从表单中显示它。在这种情况下,新表单将在所有UIView
    4. 的顶部显示为单独的UIView