I have a Firemonkey multi device project in Delphi 10 Seattle where the user can get a screen at the start of the app. Here the user needs to fill in 2 fields. But when I click on the edit fields the Virtual Keyboard isn't shown. If I skip this screen at start and call it later then the Virtual Keyboard is shown. This is done in the same way too.
I found sort of a solution: When i click on the edit fields i call show VirtualKeyboard myself. The only problem is that the cursor isn't shown in the edit field.
Is there a way to place the cursor myself? Or does anyone know how to solve the Virtual Keyboard not showing problem in an other way?
Problem is on both Android and iOS
In the code below you can see the initial form create. The problem is when in ConnectFromProfile method the actCreateNewProfileExecute is called. There it will call a new form. In that form(TfrmProfile) the virtual keyboard isn't shown. I also call this form with another action and then it works fine.
procedure TfrmNocoreDKS.FormCreate(Sender: TObject);
begin
Inherited;
System.SysUtils.FormatSettings.ShortDateFormat := 'dd/mm/yyyy';
CheckPhone;
ConnectfromProfile;
if not Assigned(fProfileAction) then
ConnectDatabase
Else
lstDocuments.Enabled := False;
{$IFDEF ANDROID}
ChangeComboBoxStyle;
{$ENDIF}
end;
procedure TfrmNocoreDKS.ConnectfromProfile;
begin
fdmProfileConnection := TdmConnection.Create(nil);
fdmProfileConnection.OpenProfileDb;
fdmProfileConnection.LoadProfiles;
if fdmProfileConnection.Profiles.Count = 0 then
begin // Createdefault Profile
fProfileAction := actCreateNewProfileExecute;
end
else if fdmProfileConnection.Profiles.Count = 1 then
begin // one profile load connection;
fProfileAction := nil;
fCurrentProfile := fdmProfileConnection.Profiles.Items[0];
end
else
begin // multiple profiles choose connection;
fProfileAction := SelectProfileOnStartUp;
end;
end;
procedure TfrmNocoreDKS.FormShow(Sender: TObject);
begin
if Assigned(fProfileAction) then
fProfileAction(Self);
end;
procedure TfrmNocoreDKS.actCreateNewProfileExecute(Sender: TObject);
var
profilename, databasename, pathname: string;
prf: TfrmProfile;
begin
prf := TfrmProfile.Create(nil);
prf.Data := fdmProfileConnection.Profiles;
prf.ShowModal(
procedure(ModalResult: TModalResult)
begin
if ModalResult = mrOk then
begin
profilename := prf.edtProfilename.Text;
databasename := prf.edtDatabaseName.Text;
{$IFDEF IOS}
pathname := System.IOUtils.TPath.GetDocumentsPath;
{$ENDIF}
{$IFDEF ANDROID}
pathname := System.IOUtils.TPath.GetDocumentsPath;
{$ENDIF}
{$IFDEF WIN32}
pathname := ExtractFilePath(ParamStr(0)) + '\Data';
{$ENDIF}
FDSQLiteBackup1.Database := System.IOUtils.TPath.Combine(pathname,
'default.sqlite3'); // Default Database
FDSQLiteBackup1.DestDatabase := System.IOUtils.TPath.Combine(pathname,
databasename + '.sqlite3');
FDSQLiteBackup1.Backup;
fdmProfileConnection.AddProfile(databasename + '.sqlite3', profilename);
fdmProfileConnection.LoadProfiles;
fCurrentProfile := fdmProfileConnection.Profiles.Items[0];
connectDatabase;
end else
Application.Terminate;
end);
end;
Do not show any additional forms in
MainForm.OnCreate/OnShow
. Trying this on iOS 9.2 freeze app at "launch screen".Instead of this, show new form asynchronously, like this:
of cource, you can separate this code to external procedures:
========
Another way - do not use any additional forms. Create frame and put it (at runtime) on MainForm with
Align = Contents
. After all needed actions - hide or release (due to ARC dont forget to set nil to frame variable) this frame.