Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 6d02512

Browse files
committed
Improved interpolation accuracy
1 parent 3728335 commit 6d02512

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

shell/platform/darwin/ios/framework/Source/FlutterViewController.mm

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,11 @@ - (void)handleKeyboardNotification:(NSNotification*)notification {
13561356
self.keyboardAnimationIsShowing = keyboardWillShow;
13571357

13581358
if (!keyboardAnimationIsCompounding) {
1359+
// Match the begin frame of the keyboard notification to ensure spring interpolation accuracy.
1360+
self.originalViewInsetBottom =
1361+
([self mainScreenIfViewLoaded].bounds.size.height - beginKeyboardFrame.origin.y) *
1362+
[self mainScreenIfViewLoaded].scale;
1363+
13591364
[self startKeyBoardAnimation:duration];
13601365
}
13611366
}
@@ -1524,7 +1529,7 @@ - (void)startKeyBoardAnimation:(NSTimeInterval)duration {
15241529
return;
15251530
}
15261531

1527-
// When call this method first time,
1532+
// When this method is called for the first time,
15281533
// initialize the keyboardAnimationView to get animation interpolation during animation.
15291534
if ([self keyboardAnimationView] == nil) {
15301535
UIView* keyboardAnimationView = [[UIView alloc] init];
@@ -1543,7 +1548,6 @@ - (void)startKeyBoardAnimation:(NSTimeInterval)duration {
15431548
[self keyboardAnimationView].frame =
15441549
CGRectMake(0, _viewportMetrics.physical_view_inset_bottom, 0, 0);
15451550
self.keyboardAnimationStartTime = fml::TimePoint().Now();
1546-
self.originalViewInsetBottom = _viewportMetrics.physical_view_inset_bottom;
15471551

15481552
// Invalidate old vsync client if old animation is not completed.
15491553
[self invalidateKeyboardAnimationVSyncClient];
@@ -1619,8 +1623,23 @@ - (void)setupKeyboardAnimationVsyncClient {
16191623
flutterViewController.get().keyboardAnimationStartTime;
16201624
double keyboardAnimationStop =
16211625
[[flutterViewController keyboardSpringCurve] curveFunc:timeElapsed.ToSecondsF()];
1622-
flutterViewController.get()->_viewportMetrics.physical_view_inset_bottom =
1623-
start + (end - start) * keyboardAnimationStop;
1626+
double newY = start + (end - start) * keyboardAnimationStop;
1627+
1628+
// When a running animation is interrupted with the opposite animation (e.g. show interrupted
1629+
// with hide), adjust the spring curve until the model catches up with the current
1630+
// bottomInset.
1631+
double currentViewInsetBottom =
1632+
flutterViewController.get()->_viewportMetrics.physical_view_inset_bottom;
1633+
double keyboardSpringFrameAdjustment = 0;
1634+
while ((start > end && currentViewInsetBottom < newY) ||
1635+
(end > start && currentViewInsetBottom > newY)) {
1636+
keyboardSpringFrameAdjustment += 1.0 / [DisplayLinkManager displayRefreshRate];
1637+
keyboardAnimationStop = [[flutterViewController keyboardSpringCurve]
1638+
curveFunc:timeElapsed.ToSecondsF() + keyboardSpringFrameAdjustment];
1639+
newY = start + (end - start) * keyboardAnimationStop;
1640+
}
1641+
1642+
flutterViewController.get()->_viewportMetrics.physical_view_inset_bottom = newY;
16241643
[flutterViewController updateViewportMetrics];
16251644
}
16261645
};

0 commit comments

Comments
 (0)