Papercloud / KeyboardConstraint

A NSLayoutConstraint subclass which observes keyboard notifications.
MIT License
14 stars 2 forks source link

iPhone X - Space above keyboard #10

Open ezescaruli opened 6 years ago

ezescaruli commented 6 years ago

I've tried KeyboardConstraint in an iPhone X and it's having an issue when the keyboard appears. It looks like this (note the space between the sign up button and the keyboard):

image

I debugged the point in which the keyboard appears: https://github.com/Papercloud/KeyboardConstraint/blob/bcd2a3e9da89cd39d74332784583e348aef0c84a/KeyboardConstraint/KeyboardAdjustConstraint.m#L65 and had this:

(lldb) po [self firstItem]
<UILayoutGuide: 0x6000005acf60 - "UIViewSafeAreaLayoutGuide", layoutFrame = {{0, 0}, {375, 690}}, owningView = <UIView: 0x7fb63fc06df0; frame = (0 88; 375 724); autoresize = W+H; layer = <CALayer: 0x600000024b80>>>

and then I did:

(lldb) po [[self firstItem] conformsToProtocol:@protocol(UILayoutSupport)]
error: cannot find protocol declaration for 'UILayoutSupport'

The debugger doesn't find the UILayoutSupport protocol declaration, which is weird...

In runtime, what happens is that the above condition resolves to NO, so the execution never falls in the line that decrements keyboardHeight, and that's why we still have that extra space in the screenshot.

I've tried replacing the fix with this, and it seems to be working fine:

- (void)_keyboardDidChangeVisible:(NSNotification *)notification {
    ...

    if (notification.name == UIKeyboardWillShowNotification) {
        if (@available(iOS 11.0, *)) {
            UILayoutGuide *layoutGuide = [self layoutGuideItem];

            if (layoutGuide != nil) {
                keyboardHeight -= layoutGuide.owningView.safeAreaInsets.bottom;
            }
        }
    }

    ...
}

- (UILayoutGuide *)layoutGuideItem {
    if ([self.firstItem isKindOfClass:[UILayoutGuide class]]) {
        return self.firstItem;
    }

    if ([self.secondItem isKindOfClass:[UILayoutGuide class]]) {
        return self.secondItem;
    }

    return nil;
}
ezescaruli commented 6 years ago

@markst What do you reckon? I know that the fix that we merged the other day worked for you, but for some reason it didn't work when I tried it (both in a simulator and a device), so I replaced it with the code I posted above to make it work.

But maybe I'm doing something wrong...?

markst commented 6 years ago

Yo @ezescaruli. Thanks for the concise issue report. We were aware of this when supporting iPhone X, see comments: https://github.com/Papercloud/KeyboardConstraint/pull/9#issuecomment-358483288

Are you sure you're using the bottomLayoutGuide when attaching the keyboard constraint? Since the bottom layout guide resolves to the safe area insets on an iPhone X.

The layoutGuide.length is considered when calculating the keyboard height: https://github.com/Papercloud/KeyboardConstraint/blob/master/KeyboardConstraint/KeyboardAdjustConstraint.m#L67

ezescaruli commented 6 years ago

@markst So, the sign up button bottom constraint looks like this:

image

The layoutGuide.length is considered when calculating the keyboard height

Yep that's right, however the issue in my case is that the execution is not reaching that line because both

[self.firstItem conformsToProtocol:@protocol(UILayoutSupport)]

and

[self.secondItem conformsToProtocol:@protocol(UILayoutSupport)]

resolve to NO. I think the reason is that the safe area layout guides are instances of UILayoutGuide, but don't conform to the UILayoutSupport protocol.

markst commented 6 years ago

@ezescaruli as mentioned you need to use the bottomLayoutGuide as example:

image

ezescaruli commented 6 years ago

@markst I don't have the bottom layout guide among the options 🤔

image

I could probably make it appear if I disable Use Safe Area Layout Guides in the storyboard file inspector, but that would not be ideal, would it?

markst commented 6 years ago

Yup you need to disable safe area guides in the interface builder settings:

By all means have a crack at getting it to work fine for safe area insets. Just be sure you don't break it for bottomLayoutGuide.

ezescaruli commented 6 years ago

@markst Perfecto, I'll give a try and check if the fix I made above works for the bottom layout guide too 👍