Skip to content

Update virtual keyboard and safe area handling for iOS 16+ and Android 12+ #13

@jimmckeeth

Description

@jimmckeeth

Overview

The training code implements manual virtual keyboard avoidance by tracking FormVirtualKeyboardShown / FormVirtualKeyboardHidden events and manually adjusting a TVertScrollBox content bounds. iOS 16+ and Android 12+ have changed how the system keyboard interacts with app windows, and Delphi 13's FMX runtime has updated virtual keyboard support that makes some of this manual code unnecessary or incorrect.

Background

Current Manual Approach

{$IF DEFINED(ANDROID) OR DEFINED(IOS)}
  VKAutoShowMode := TVKAutoShowMode.Always;
  VSB.OnCalcContentBounds := CalcContentBoundsProc;
{$ENDIF}

procedure CalcContentBoundsProc(Sender: TObject; var ContentBounds: TRectF);
begin
  // Manually adjust bounds based on keyboard height
  ContentBounds.Bottom := ContentBounds.Bottom + FKeyboardOffset;
end;

What Changed

  • iOS 16: UIKit now uses the keyboard layout guide (UIKeyboardLayoutGuide) — the system automatically handles layout adjustment if Auto Layout is used. FMX apps don't use Auto Layout directly, but Delphi 13's FMX layer was updated to respond to UIKeyboardLayoutGuide.
  • Android 12 (API 31): WindowInsets API (WindowInsetsController) replaces the older adjustResize/adjustPan approach. The android:windowSoftInputMode setting in the manifest interacts with this new API.
  • Delphi 12+: FMX introduced TVirtualKeyboardState improvements and the IFMXVirtualKeyboardService interface was updated.

The manual CalcContentBoundsProc may double-adjust the layout if Delphi 13's own keyboard avoidance is also active, causing the content to scroll too far.

Files Affected

lab-src/Lab*/forms/formMain.pas  (VKAutoShowMode setup, keyboard event handlers)
lab-src/Lab*/frames/uNewEntryFrame.pas  (CalcContentBoundsProc)
lab-src/Lab*/AndroidManifest.template.xml  (windowSoftInputMode)

Steps to Address

  1. Test the current keyboard avoidance code against Delphi 13 on both platforms to determine if the manual adjustment is still needed or now conflicts with the framework.
  2. If Delphi 13 handles keyboard avoidance automatically for TVertScrollBox, remove or simplify CalcContentBoundsProc.
  3. If manual handling is still needed, update the bounds calculation to use the IFMXVirtualKeyboardService.VirtualKeyboardBounds property correctly for the current Delphi 13 API.
  4. In AndroidManifest.template.xml, verify the android:windowSoftInputMode value (adjustResize vs adjustNothing) is appropriate for API 31+ behavior.
  5. Test with gesture navigation (Android 10+ swipe gestures) where the navigation bar is hidden, as keyboard insets behave differently.
  6. Verify that TVKAutoShowMode.Always is still the correct mode for the training's use case in Delphi 13.
  7. Update lab instructions to reflect current best practices for keyboard handling.

Test Plan

  • On Android 13 emulator with gesture navigation: tapping a text field scrolls the focused field into view above the keyboard.
  • On Android 13 emulator with 3-button navigation: same behavior.
  • On iOS 17 simulator: tapping a text field in the entry form scrolls it above the keyboard without over-scrolling.
  • Dismissing the keyboard (swipe down or tap outside): the content returns to its original position without jumping.
  • No double-scroll behavior (content doesn't jump too far then snap back).
  • On Android, rotating from portrait to landscape while keyboard is open: layout reflows correctly.
  • All text fields in all labs are accessible when the keyboard is shown.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions