4

我们开始将我们现有的 iOS (XCode) 应用程序之一移植到 Delphi FireMonkey (XE4)。到目前为止,这是一个令人惊讶的顺利过程。但是,我们遇到了一个死胡同,我们不知道如何解决。

我们现有的应用程序类似于新的Google 地图应用程序。我们有一个webbrowser控件,它显示包含许多 pin 的 Google Map。我们还有一个设置按钮和一个信息面板,它会在点击 pin 时出现。按下相应的按钮/图钉时,设置和信息面板会从地图的左右两侧滑入。这一切都在 XCode 应用程序中运行良好。

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

  • 我们无法在 webbrowser 控件的顶部显示 FireMonkey 控件。我知道这是因为网络浏览器是本机 iOS 控件。
  • 一旦 webbrowser 控件出现,它就无法移动,例如,如果我们更改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.

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

在此处输入图像描述

以下是我的观察:

  • 单击按钮没有任何效果。
  • 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 就会关闭弹出窗口(破坏弹出窗体)。更奇怪的是,带有网络浏览器的弹出窗口在它应该关闭后仍然可见,即使它在单击时没有反应。

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

此外,弹出窗口的父标签仍显示在主窗体拥有的网络浏览器下。

更新 3

我发现了许多问题,但修复它们并不能使它更好地工作。

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

代码:

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;
4

1 回答 1

2

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

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

为了解决您的问题,您可以:

  1. 创建新表单或弹出表单
  2. 为其设置大小和位置。
  3. 使用 WebBrowser 从表单中显示它。在这种情况下,新表单将作为一个单独的 UIView 显示在所有 UIView 的顶部
于 2013-08-02T13:23:09.763 回答