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

[iOS] [iPad] fix avoid bottom inset in split view mode #35535

Conversation

RichardFevrier
Copy link

Fix flutter/flutter#109845

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@cyanglaz
Copy link
Contributor

Looks like the bug wasn't what I thought in flutter/flutter#109845 (comment).

@LongCatIsLooong @justinmc Are you the right people to review this?

@RichardFevrier, tests need to be added in order for this PR to land.

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

Happy to review it! I'm no expert on the iOS embedder but this seems reasonable to me. +1 that this needs tests.

I don't know why we used keyboardWillBeHidden in the first place instead of keyboardWillChangeFrame. Seems like this should all still work though, but me or someone else should probably try this out locally and confirm that nothing seems broken.

@@ -1190,12 +1185,19 @@ - (void)updateViewportPadding {

#pragma mark - Keyboard events

// using keyboardWillChangeFrame instead of keyboardWill(Show/Hide) because of split/floating
// keyboard on iPad
Copy link
Contributor

Choose a reason for hiding this comment

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

Capital letter at the beginning and period at the end. Also maybe link to the issue.

Copy link
Author

Choose a reason for hiding this comment

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

I'll fix that this week 👍


// Ignore keyboard notifications related to other apps.
// Ignore keyboard notifications related to other apps if not dismissing.
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if you show the keyboard in the other app, then tap the Flutter app's text field?

I haven't tried it, just curious.

Copy link
Author

Choose a reason for hiding this comment

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

It works normally,

  1. the keyboard appear on the other app and the other app is resized
  2. the textfield in the flutter app becomes the first responder so the flutter app is resized at that moment.

I can make a video if necessary

[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[self startKeyBoardAnimation:duration];
}
// Get the animation duration
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Period at the end (I know you didn't write this comment, but it's a good chance to fix it! 😁).

Copy link
Author

Choose a reason for hiding this comment

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

I'll fix that this week 👍

Copy link
Contributor

@cyanglaz cyanglaz left a comment

Choose a reason for hiding this comment

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

Can we also make sure this change doesn't regress flutter/flutter#99951

@@ -1190,12 +1185,19 @@ - (void)updateViewportPadding {

#pragma mark - Keyboard events

// using keyboardWillChangeFrame instead of keyboardWill(Show/Hide) because of split/floating
Copy link
Contributor

Choose a reason for hiding this comment

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

The comment says "keybaordWill(show/hide), but we don't have a "keyboardWillShow", maybe just "keyboardWillBeHidden"?

Copy link
Author

Choose a reason for hiding this comment

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

keyboardWillShow/keyboardWillHide are part of the UIKit framework; so keyboardWillBeHidden is not appropriated here and my comment is still relevant 🙂
BTW I tried to answer to you in my opened issue last week but I could not without closing the issue.
(nothing related but I loved the document you wrote related to blurs... so interesting to read !)


// Ignore keyboard notifications related to other apps.
// Ignore keyboard notifications related to other apps if not dismissing.
bool isDismissing =
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe:

bool isShowing = CGRectIntersection(keyboardFrame, screenRect);

Copy link
Author

Choose a reason for hiding this comment

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

Good point, I'll fix that this week 👍

id isLocal = info[UIKeyboardIsLocalUserInfoKey];
if (isLocal && ![isLocal boolValue]) {
if (!isDismissing && isLocal && ![isLocal boolValue]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Have you tested If the keyboard is brought be by the other app, does the Flutter app's bottom inset adjust? This logic here seems to prevent Flutter app's bottom inset to be adjusted to the correct value in that case. Which is what I was saying in: flutter/flutter#109845 (comment)

Copy link
Author

Choose a reason for hiding this comment

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

As I wrote to @justinmc, if the keyboard is brought by an other app:

  1. the keyboard appear on the other app and the other app is resized
  2. (if you tap in the textfield on the flutter app) the textfield in the flutter app becomes the first responder so the flutter app is resized at that moment.

This is the correct behavior since natives apps have that one.

// Get the animation duration
NSTimeInterval duration =
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

// Considering the iPad's split keyboard, Flutter needs to check if the keyboard frame is present
// in the screen to see if the keyboard is visible.
if (CGRectIntersectsRect(keyboardFrame, screenRect)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This line can be changed to if (isShowing) { if you take my suggestion above.

Copy link
Author

Choose a reason for hiding this comment

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

I'll fix that this week 👍

@RichardFevrier
Copy link
Author

I don't know why we used keyboardWillBeHidden in the first place instead of keyboardWillChangeFrame. Seems like this should all still work though, but me or someone else should probably try this out locally and confirm that nothing seems broken.

Worse than that @justinmc, it calls twice the animation via startKeyBoardAnimation and can probably be related with flutter/flutter/issues/109435

Also something that I wanted to say the week before without closing the issue is:
I do not know why the CI failed at testEnsureBottomInsetIsZeroWhenKeyboardDismissed since this PR can only improve that...

Can we also make sure this change doesn't regress flutter/flutter#99951

I can try that @cyanglaz on my iPad but is there not a Unit test to check it automatically?

And last point, I am okay to make a Unit Test to avoid regressions on that point, but is it possible to write Unit test for split view apps with your framework?

Thanks.

@luckysmg
Copy link
Contributor

luckysmg commented Sep 1, 2022

Maybe just delete the code below can fix this?

// Delete this code in keyboardWillBeHidden
  id isLocal = info[UIKeyboardIsLocalUserInfoKey];
  if (isLocal && ![isLocal boolValue]) {
    return;
  }

@luckysmg
Copy link
Contributor

luckysmg commented Sep 7, 2022

Updated: keyboardWillChangeFrame will include show/hide/changeFrame so maybe keyboardHidden seems to be redundant.

So this look seems better, and we just need to make sure that the
bool isDismissing = CGRectEqualToRect(keyboardFrame, CGRectZero) || keyboardFrame.origin.y >= screenRect.size.height; or
bool isShowing = CGRectIntersectsRect(keyboardFrame, screenRect);
is accurate to judge whether the keyboard is open or close currently😄.

@jmagman
Copy link
Member

jmagman commented Sep 14, 2022

@RichardFevrier were you able to figure out how to write the split view mode integration tests? Also it looks like @luckysmg had some suggestions.
@cyanglaz was this ready for re-review or are you waiting for the unit tests?

@cyanglaz
Copy link
Contributor

I can try that @cyanglaz on my iPad but is there not a Unit test to check it automatically?

We do have unit-tests cover it but not integration test. It would be nice to at least do a manual test to make sure it is not regressed. If it is, then we will need to add better tests for flutter/flutter#99951

I think we can land this PR when 1. Unit-tests (or even better integration tests) are added, 2. When we did a manual test that flutter/flutter#99951 is not regressed.

@chinmaygarde
Copy link
Member

It seems like this is still WIP. Adding the labels. If OTOH no progress is being made, perhaps we can close this?

@chinmaygarde chinmaygarde added the Work in progress (WIP) Not ready (yet) for review! label Sep 22, 2022
@flutter-dashboard
Copy link

This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold.

@jmagman jmagman requested a review from vashworth November 9, 2022 21:14
@jmagman
Copy link
Member

jmagman commented Dec 15, 2022

@RichardFevrier Thank you for your contribution. This PR has been superseded by #37719 cc @vashworth. If you're still seeing issues related to split view mode please file new issues and we'll take a look!

@jmagman jmagman closed this Dec 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[iOS] [iPad] Bug in avoid bottom inset in split view mode
6 participants