我们开始将我们现有的 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
我发现了许多问题,但修复它们并不能使它更好地工作。
- 由于某些(莫名其妙的)原因,似乎剪切一个控件(CTRL-X),然后选择另一个控件并粘贴(CTRL-V)会将剪切控件粘贴到主窗体,而不是选定的控件。重新设置控件的唯一方法是将其拖放到结构树中。
- 在将控件重新设置为 PopUp 之后,我现在只要调用 Popup1.Popup(FALSE) 就会得到一个异常。这很可能是因为弹出窗口显示在 Create 事件中。将其移动到 OnClick 事件可以消除异常。
- 似乎为了在单击主窗体时停止弹出窗口关闭,您应该在调用 .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;