Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS 12 App Touch-Areas are offset after keyboard is hidden #814

Closed
ghost opened this issue Sep 21, 2018 · 41 comments
Closed

iOS 12 App Touch-Areas are offset after keyboard is hidden #814

ghost opened this issue Sep 21, 2018 · 41 comments

Comments

@ghost
Copy link

ghost commented Sep 21, 2018

Steps to reproduce:

  • Type into an input, which will scroll the Application's view
  • Press a button, while the input is focued

What happens:
-> The UI shifts down, but touchareas of UI-Elements are still offset. Causing always touching the wrong button

Tested with iPhone X and iPhone 8 Simulator on iOS 11 and iOS 12.
Only happens on iOS 12 (both Simulators)

When you take a look at the View Hierarchy it seems, some Subviews of the WebView are still offset.
Screenshot of Hierarchy attached.

bildschirmfoto 2018-09-21 um 18 29 11

@jcesarmobile
Copy link
Member

jcesarmobile commented Sep 21, 2018

Are you using Xcode 10, right?
I think this is a bug in the SDK 12 included in Xcode 10.

Can you try with Xcode 9 and see if you can reproduce there?

But testing directly from Xcode 9 in iOS 12 devices is not possible as it fails to install, you'll have to export the ipa and install it manually

@ghost
Copy link
Author

ghost commented Sep 21, 2018

You are right, does not happen with Xcode 9 / iOS 11.
But when you open an URL and load a website in a WKWebView everything works fine with iOS 12.
So it seems there is an issue in the Capacitor-Layer.

@jcesarmobile
Copy link
Member

I meant, can you test this in Xcode 9 but on iOS 12 device?

@ghost
Copy link
Author

ghost commented Sep 25, 2018

Just tried it, built with Xcode 9 and run on iOS 12 device works fine.

@luke-rogers
Copy link

luke-rogers commented Sep 27, 2018

I am also seeing this issue when using keyboard which causes input to scroll into view (may be through using keyboard arrows) then closing the keyboard, the buttons in my toolbar cannot be clicked. When you press them nothing happens. This issue is consistently reproducible and makes the app unusable.

Inline with this issue, it does not seem to affect my app when running on iOS 11.

Not super sure the cause of this issue, many issues have been raised across other projects, but it is also effecting capacitor apps.
ionic-team/cordova-plugin-ionic-webview#176
apache/cordova-ios#417
http://www.openradar.me/44655885

Potential test project https://github.com/dpogue/WKScrollTest

@nikmartin
Copy link

nikmartin commented Oct 1, 2018

We just filed the same bug against ionic 4, but was told it was probably a capacitor issue as far as ionic is concerned, so rather than open another issue, I'll paste it here:

Ionic Info
Run ionic info from a terminal/cmd prompt and paste the output below.

ionic (Ionic CLI)          : 4.1.0 (/usr/local/lib/node_modules/ionic)
   Ionic Framework            : @ionic/angular 4.0.0-beta.7
   @angular-devkit/core       : 0.7.5
   @angular-devkit/schematics : 0.7.5
   @angular/cli               : 6.1.5
   @ionic/ng-toolkit          : 1.0.8
   @ionic/schematics-angular  : 1.0.6

System:

   NodeJS : v8.11.4 (/usr/local/bin/node)
   npm    : 5.6.0
   OS     : macOS High Sierra

Describe the Bug
When the on screen keyboard is displayed and hidden (from a footer input), it causes the UI to be scrolled up, the user interface is 'shifted' up by the width of the keyboard. When the keyboard then disappears, all the UI input is still shifted up by the width of the keyboard. This means all clicks in the UI are too high (ie inputs, etc). Also, when an input is in the content area, the keyboard will hide the input instead of scrolling it as it should.

Steps to Reproduce
Steps to reproduce the behavior:

  1. Clone: https://github.com/grabitlogistics/ios12kbd
  2. run npm i && ng build && npx cap add ios && npx cap copy ios && npx cap open ios
  3. build and run the app on an ios 12 device
  4. Click in an upper input to display the keyboard, then click outside to hide the keyboard and lose focus.
  5. Click on an input in the footer, making the keyboard appear and shift the inputs up. Click outside the input to hide the keyboard.
  6. All touch events have now been shifted up by the height of the keyboard, so to click in the input in the content OR the footer, you must click a few inches above the respective input (about the height of the keyboard)

Related Code
sample test case: https://github.com/grabitlogistics/ios12kbd

Additional Context
This ONLY happens on iOS 12, on a hardware device OR emulator. To test in an emulator, you must use the emulated keyboard in order to cause the UI to shift up.

@hghammoud
Copy link

I did some testing on multiple ios/emulators
XCode 10.0

iPhone 8 Plus iOS 11 -> no view shits everything is ok
iPhone 8 Plus iOS 12 -> no view shits everything is ok
IPhone X iOS 11.3 -> view shits but clicks are in place ()
IPhone X ans XS iOS 12 -> view shits and clicks are not accurate (the click action triggers lower the the touch point - same amount of view shit)

it seems related seems related to the extra track pad.
image

@YodaVN
Copy link

YodaVN commented Oct 20, 2018

Anyone has the fix of this problem?

@sbannigan
Copy link
Contributor

sbannigan commented Oct 23, 2018

Can confirm that this issue exists in Cordova on iOS 12 as well apache/cordova-ios#417

@KhanhPhamDinh
Copy link

KhanhPhamDinh commented Oct 24, 2018

Hi all, i am facing that issue run on IOS 12 that was built with Xcode 10 (if you build with XCode 9, the issue don't appear). The root cause of issue is WKScrollview in WKWebview will be changed automatically content offset fit with height of keyboard in case keyboard is showed, but it didn't reset in case keyboard is hidden. That is my solution to fixed it, hope it help for you.

/**
 * observer notification when keyboard will hide
 */
[[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillHide)
                                                     name:UIKeyboardWillHideNotification
                                                   object:nil];

/////////////--------------------------//////////////
/*
 *Description: this method was trigger by selector keyboarwillhide from notification
 */
-(void)keyboardWillHide
{
    if (@available(iOS 12.0, *)) {
        WKWebView *webview = (WKWebView*)self.webView;
         for(UIView* v in webview.subviews){
            if([v isKindOfClass:NSClassFromString(@"WKScrollView")]){
                UIScrollView *scrollView = (UIScrollView*)v;
                [scrollView setContentOffset:CGPointMake(0, 0)];
             }
          }
     }
}

@JacoRoos
Copy link

@jcesarmobile Regarding this comment: #814 (comment)

Is it not possible to set the SDK that XCode uses to build instead of having to install another version of XCode?

@jcesarmobile
Copy link
Member

Here it says you can but it present a few problems
https://stackoverflow.com/questions/44985307/xcode-9-how-to-install-ios-10-sdk

@JacoRoos
Copy link

OK, thanks for the feedback! Looks like it would be more of a headache to do this than installing an additional version of XCode.

@sarapoll
Copy link

any solution?

@hghammoud
Copy link

This was merged in corodva ionic webview
ionic-team/cordova-plugin-ionic-webview@a670568

Anyone knows how to integrate it with capacitor (I am not using cordova plugin)?

@oliverandersencox
Copy link

this is exactly the problem I am having - any use of the keyboard completely messes up the webview container and shifts it all up

@oliverandersencox
Copy link

this happens on the IOS device itself and has completely halted any chances of pushing out to customers

@oliverandersencox
Copy link

not sure if this is related however, my app will also always load first time with a slight gap under the app displaying the WKScrollView:

screenshot 2018-11-21 at 18 20 01

screenshot 2018-11-21 at 18 34 38

If I rerun the app it will sometime disappear, other times it wont - very sporadic

@snapeuh
Copy link

snapeuh commented Nov 23, 2018

Hello, we are experiencing the same bug on iOS 12. When the keyboard closes, the webview keeps a "padding" from the bottom like if the keyboard was still visible.

@moberwasserlechner
Copy link
Contributor

Same here. But only after I upgraded to beta.11.

On every view I use the keyboard the whole app is shifts up and stays there until I rotate my phone to landscape and back.

Tabbed email input field with keyboard displayed.
img_3354
Keyboard loses focus and disappears but view stays shifted up.
img_3355

This is a blocker for all apps using the keyboard.

I experience the problem with XCode 10 and XCode 10.1 deployment target was 11.0.

@moberwasserlechner
Copy link
Contributor

moberwasserlechner commented Nov 26, 2018

I adapted the solution from #814 (comment) to Swift and used it in the ios/App/App/AppDelegate.swift.

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    
    return true
  }
    
    @objc func keyboardWillHide(notification: NSNotification) {
        if #available(iOS 12.0, *) {
            let vc = self.window?.rootViewController as! CAPBridgeViewController
            for v in vc.bridgedWebView!.subviews {
                if v is UIScrollView {
                    let scrollView = v as! UIScrollView
                    scrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
                }
            }
        }
    }

This fixes my issues.

@dabaaaz
Copy link

dabaaaz commented Nov 28, 2018

That last solution works fine !
But I got a problem when I released. The AppDelegate.swift file is not taking into consideration, because of an optimization level during the release build.

That problem can be fixed by disabling the release optimizations :
In Xcode and "Build Settings", seek "optimization level" and select "None [-O0]".

@rj33
Copy link

rj33 commented Dec 3, 2018

As well as the keyboard input issues, I appear to be having essentially the same problem with the UI that pops up to handle selection of choices in a form select element.

@pixelbucket-dev
Copy link

I had the same issue. My fix was to add the following code to the index.html:

    window.addEventListener('keyboardWillHide', () => {
        window.scrollTo(0,0);
	document.body.scrollTop = 0;
    });

@nicdichiara
Copy link

nicdichiara commented Dec 10, 2018

I had the same issue. My fix was to add the following code to the index.html:

    window.addEventListener('keyboardWillHide', () => {
        window.scrollTo(0,0);
	document.body.scrollTop = 0;
    });

Can confirm this works as a workaround, even if you update xcode to 10.1. Thank you @NudelSieb !!

@vuthanhict
Copy link


 if #available(iOS 11.0, *) {
             self.webView.scrollView.contentInsetAdjustmentBehavior = .never
 } else {
            self.automaticallyAdjustsScrollViewInsets = false
 }

And UIScrollViewDelegate

 func scrollViewDidChangeAdjustedContentInset(_ scrollView: UIScrollView) {
       Logger.print("scrollViewDidChangeAdjustedContentInset")
         if #available(iOS 12.0, *) {
           for view in webView.subviews {
                if let scrollView = view as? UIScrollView {
                   scrollView.setContentOffset(.zero, animated: true)
                 }
             }
        }
}

Worked

@christophersansone
Copy link

FWIW, I implemented @NudelSieb's solution above, with a couple caveats.

  1. It requires cordova-plugin-keyboard for the keyboardWillHide event to trigger.

  2. When immediately transitioning from one input to another, the keyboardWillHide event will trigger, even though the keyboard does not actually have time to hide. That seemed to cause undesired scrolling. I added a setTimeout() to prevent it from executing immediately, which helped.

const scrollToTopFn = () => {
  if (window.Keyboard && !window.Keyboard.isVisible) {
    window.scrollTo(0,0);
    window.document.body.scrollTop = 0;
  }
};

window.addEventListener('keyboardDidHide', () => {
  window.setTimeout(scrollToTopFn, 100);
});

@thestevenmellor
Copy link

thestevenmellor commented Dec 29, 2018

Finally got it to work.. I had to piece together this file here: fix keyboard displacement bug in iOS 12 WKWebView from @hghammoud

A straight copy didn't work, but taking each part and adding it to my CDVWKWebViewEngine.m file worked for me. I'll post my file if anyone needs it.

Here's my setup:
Ionic:
ionic (Ionic CLI) : 4.6.0
Ionic Framework : ionic-angular 3.9.2
@ionic/app-scripts : 3.1.10

Cordova:
cordova (Cordova CLI) : 8.1.2 ([email protected])
Cordova Platforms : android 7.1.4, ios 4.5.5
Cordova Plugins : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 1.1.1, (and 18 other plugins)

System:
ios-deploy : 1.9.2
NodeJS : v6.15.1 (/usr/local/Cellar/node/11.5.0/bin/node)
npm : 3.10.10
OS : macOS Mojave
Xcode : Xcode 10.1 Build version 10B61

@zenochan
Copy link

  1. template
    <input  (blur)="scrollToTop()">
  1. page
  scrollToTop()
  {
    window.scrollTo(0,0);
  }
  1. down

@sooheesh
Copy link

@longbo666
Copy link

期待有人能真正解决

@daniellizik
Copy link

You are right, does not happen with Xcode 9 / iOS 11.
But when you open an URL and load a website in a WKWebView everything works fine with iOS 12.
So it seems there is an issue in the Capacitor-Layer.

I can still reproduce this with iOS 11.4.1 and xcode 9.4.1

@jcesarmobile
Copy link
Member

I think this should be fixed in next release, I made a few keyboard changes that combined seem to fix it.

@daniellizik what you comment should be a different issue as this only affects iOS 12 when using Xcode 10, not iOS 11 despite the Xcode version, and doesn't affect any iOS version when using Xcode 9.

@alphagamer7
Copy link

@jcesarmobile Confirming that even with the latest release (4.0.2) the issue is not fixed.

@jcesarmobile
Copy link
Member

Not sure what 4.0.2 you mean, but I’m talking about next capacitor release (1.0.0 beta 18, still not released)

@MarcAndreC
Copy link

@jcesarmobile Is the fix that you've made is in a branch that we can test?

@jcesarmobile
Copy link
Member

Beta 18 is out, can you test with it?

@solojuve1897
Copy link
Contributor

@jcesarmobile
Part of this bug is fixed but there is still strange behaviour. Check my video:

https://drive.google.com/file/d/11Msg2lSiW1UoN-si6nL1QxLS93shBu9h/view

None of these occur on my Android-devices.

@calvinckho
Copy link

calvinckho commented Mar 7, 2019

@jcesarmobile it is working great on my iPhone 7 test device running iOS 12! It seems to have completely fixed the bug introduced by Apple's webview in iOS 12. Thanks for this update.

@davidrinnan
Copy link

when the given page loads, if it is ios etc etc, I attach a listener
document.addEventListener('focusout', resetScroll);

reset scroll is running on a short timeout and checks if the innerheight and height is the same, if se, it resets the scroll. This results in the scroll only being reset once the keyboard is removed from screen, rather than everytime the focus is changed.

 setTimeout(()=>{
        if (window.innerHeight == screen.height) {
            window.scrollTo(0, 0)    
        }
    },timeout);

@jcesarmobile
Copy link
Member

I can't reproduce since beta 18 and calvinckho also confirmed that it's working fine for him, so I'm going to close.
For other strange behaviours report new issues.

@ionic-team ionic-team locked as resolved and limited conversation to collaborators Mar 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests