FireMonkey controls based on iOS controls not behaving correctly

We are starting to port one of our existing iOS apps (Xcode) to Delphi FireMonkey (XE4). Until now, it has been an amazingly smooth process. However, we are at an impasse, and we do not know how to solve this.

Our existing application is similar to the new Google Maps application. We have a webbrowser control that displays a Google map containing multiple contacts. We also have a settings button and an information panel that appears when a pin screams. When you press the corresponding button / conclusions, the settings and information panels slide on the map left and right. All this works great in the Xcode application.

Here are the problems we have with the FireMonkey port:

  • We cannot display the FireMonkey control on top of the control web browser. I understand that this is due to the fact that webbroswer is native iOS.
  • Once a web browser control appears, it cannot be moved, for example. if we change the position.x property, the web browser will remain where it is. This is the same if we change the x property using inline animation. The only property that works correctly is visible .

Using TMS iCL components, we can fix the first problem. However, the most disturbing problem for us is the second. Unable to move the webbrowser component, it is impossible to implement a modern (sliding) user interface that uses a web browser (or any native iOS control).

Does anyone have the opportunity to overcome these limitations of FireMonkey?

UPDATE 1

In accordance with the proposal of Yaroslav, I tried the following:

1) Created a second form using a button and a web browser.

 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) Created Form2 as a child of 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. 

When I launch the application, I see the following:

enter image description here

Here are my observations:

  • Pressing the buttons does not affect.
  • The Form2 button is not visible.
  • The Form2 Left property in the designer is set to 40. However, the form is displayed at 0.

Update 2:

Following the recommendations in the comments, I changed the source of Form1 to:

 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. 

Unfortunately, neither motion nor overlay work. The current code throws an exception when referencing TCustomForm (Popup1.Popupform) .Left. The reason the exception occurs is because Delphi closes the popup (destroying the popup) as soon as the left mouse event occurs in the parent form. Even stranger, a web browser popup is still visible after it has to be closed, even if it doesn’t respond when clicked.

Changing the code in Popup1.Position.X does not throw an exception, but, of course, the popup does not move anyway.

In addition, the shortcut, which is the parent of the popup, is still displayed under the web browser that belongs to the main form.

Update 3

I found several problems, but fixing them does not improve performance.

  • For some (inexplicable) reason, it seems that cutting out the control (CTRL-X) and then selecting another control and paste (CTRL-V) inserts the cutting control into the main form and not into the selected control. The only way to reinstall the control is to drag it into the structure tree.
  • After restoring the controls in PopUp, now I get an exception as soon as I call Popup1.Popup (FALSE). This is most likely because the popup is displayed in the Create event. Moving it to the OnClick event gets rid of the exception.
  • It seems that in order to stop the popup closing when the main form is clicked, you should set the StaysOpen property before calling .Popup. However, in fact, this property does not work correctly. For example, the following code turns it into a string TCustomForm (Popup1.PopupForm) .Left, but then throws an exception because the pop-up form has already been destroyed!

the code:

 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
source share
1 answer

To solve, we must know:

  • Each Firemonkey form is based on a Native UIView , which is the subordinate root representation of the Main UIViewController . Therefore, when you insert a control in the FireMonkey form, that control remains in the UIView form.
  • All standard Firemonkey controls do not have their own UIView. The FMX form has all the FMX controls and controls them.
  • Firemonkey WebBrowser is based on UIWebView and is displayed as a preview in the form of Firemonkey UIView .
  • The entire popup is based on a UIView with a transparent background. The position of the popup windows and the size of the specified properties TForm.Position, TForm.Size. Thus, you can create a form with a transparent background above on the form with TWebBrowser, set the size and set the position.

To solve your problem you can:

  • Create a new form or popup
  • Set the size and position for it.
  • Show it from a form using WebBrowser. In this case, the new form will be displayed as a separate UIView at the top of the entire UIView
+2
source

Source: https://habr.com/ru/post/1494030/


All Articles