Skip to content

Handle keyboard and orientation changes smoother#540

Open
belleklaviyo wants to merge 2 commits intofeat/flyouts-formsfrom
bl/fix-keyboard-orientation-handling
Open

Handle keyboard and orientation changes smoother#540
belleklaviyo wants to merge 2 commits intofeat/flyouts-formsfrom
bl/fix-keyboard-orientation-handling

Conversation

@belleklaviyo
Copy link
Copy Markdown
Contributor

@belleklaviyo belleklaviyo commented Apr 3, 2026

Description

Fixes two issues with in-app form window positioning: orientation changes were not animating smoothly, and keyboard avoidance was incorrectly applied to all bottom-anchored forms regardless of actual overlap.

Due Diligence

  • I have tested this on a simulator or a physical device.
  • I have added sufficient unit/integration tests of my changes.
  • I have adjusted or added new test cases to team test docs, if applicable.
  • I am confident these changes are compatible with all iOS and XCode versions the SDK currently supports.

Release/Versioning Considerations

  • Patch Contains internal changes or backwards-compatible bug fixes.
  • Minor Contains changes to the public API.
  • Major Contains breaking changes.
  • Contains readme or migration guide changes.
  • This is planned work for an upcoming release.

Changelog / Code Overview

Orientation handling

  • Replaced UIDevice.orientationDidChangeNotification with viewWillTransition(to:with:) via a new onSizeTransition callback on KlaviyoWebViewController
  • Frame updates now run inside the transition coordinator's animation block so resizes animate in sync with the device rotation

Keyboard avoidance

  • Instead of blindly subtracting keyboard height from screen bounds, the window manager now calculates the actual overlap between the keyboard and the form's bottom edge
  • The window only shifts up when there is real overlap, and only by the overlap amount — no unnecessary movement for forms that already clear the keyboard
  • Removed isBottomAnchored gate so all form positions participate in the overlap check

Test Plan

  1. Present a bottom-anchored form and rotate the device — confirm the form reframes smoothly alongside the rotation animation
  2. Present a form that doesn't reach the bottom of the screen, then show the keyboard — confirm the form does not move
  3. Present a form near the bottom of the screen, then show the keyboard — confirm the form shifts up exactly enough to clear the keyboard
  4. Dismiss the keyboard — confirm the form returns to its original position
Simulator.Screen.Recording.-.iOS.18.-.2026-04-03.at.15.45.02.mov

Related Issues/Tickets


@belleklaviyo belleklaviyo changed the base branch from master to feat/flyouts-forms April 3, 2026 20:07
@belleklaviyo belleklaviyo mentioned this pull request Apr 3, 2026
9 tasks
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

private var window: UIWindow?
private var windowScene: UIWindowScene?
private var currentLayout: FormLayout?
private weak var viewController: KlaviyoWebViewController?
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Property viewController is set but never read

Low Severity

The new private weak var viewController property is assigned in present() on line 26 via self.viewController = viewController but is never read anywhere in the class. All other references to viewController in the file (lines 39, 47, 129, 131) resolve to local method parameters, not the instance property. This is a dead store. It may have been intended for cleanup in dismiss() (e.g., clearing onSizeTransition), but that line was never added.

Additional Locations (1)
Fix in Cursor Fix in Web

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels legit. Do we need it if it's not read? Or maybe it's read and this is wrong.

window.frame = adjustedFrame
} else {
window.frame = baseFrame
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fullscreen forms shift off-screen when keyboard appears

High Severity

Removing the isBottomAnchored gate without exempting .fullscreen forms means fullscreen forms now participate in the keyboard overlap check. For fullscreen, calculateFrame returns screenBounds, so gap is always zero and overlap equals the full keyboardHeight. The window gets shifted to a negative y-origin (e.g., y = −336), clipping the top of the form off-screen. Fullscreen is the default layout (seen in IAFWebViewModel.swift), so this affects many forms. The old code correctly skipped keyboard adjustment for non-bottom-anchored positions including fullscreen.

Fix in Cursor Fix in Web

@belleklaviyo belleklaviyo marked this pull request as ready for review April 3, 2026 21:00
@belleklaviyo belleklaviyo requested a review from a team as a code owner April 3, 2026 21:00
@klaviyoit klaviyoit requested a review from ndurell April 3, 2026 21:00
@ndurell
Copy link
Copy Markdown
Contributor

ndurell commented Apr 10, 2026

Unrelated but maybe we have to deal with x moving on orientation oof.

Copy link
Copy Markdown
Contributor

@ndurell ndurell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the video looks ok to me. Not sure if it applies but might be good to rest with fullscreen.


private func setupObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(handleOrientationChange), name: UIDevice.orientationDidChangeNotification, object: nil)
private func setupObservers(on viewController: KlaviyoWebViewController) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do any of these changes affect full screen forms?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants