4

I know that this library is already deprecated, but has anyone fixed the problem with the inputToolBar and iPhone X? Currently the inputToolBar is partially covered.Check out the attached image.

enter image description here

Thanks in advance

Sami Ali
  • 163
  • 3
  • 10
  • Possible duplicate of [jsqmessageviewcontroller ios11 toolbar](https://stackoverflow.com/questions/46439975/jsqmessageviewcontroller-ios11-toolbar) – Tore Olsen Oct 24 '17 at 07:44
  • @ToreOlsen I see that you gave an answer in Objective C. Could you possibly give your answer in Swift? I tried this statement: NSLayoutConstraint *constraint = [self performSelector:@selector(toolbarBottomLayoutGuide)]; translating it to Swift but didn't work. Thanks in advance! – Sami Ali Oct 24 '17 at 08:36
  • I'm currently working on the solution I gave in that answer, as it did not solve all problems, and the new approach possibly uses swizzling which may not be possible using Swift… I'll keep that in mind when I get around to updating the answer. – Tore Olsen Oct 24 '17 at 11:34
  • FYI: I've updated my answer now. – Tore Olsen Oct 26 '17 at 09:11

6 Answers6

19

In case you don't want to change the code in the pod and use are more swifty-like extension you can use the following code:

extension JSQMessagesInputToolbar {
    override open func didMoveToWindow() {
        super.didMoveToWindow()
        guard let window = window else { return }
        if #available(iOS 11.0, *) {
            let anchor = window.safeAreaLayoutGuide.bottomAnchor
            bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow(anchor, multiplier: 1.0).isActive = true
        }
    }
}
Simon Bengtsson
  • 7,573
  • 3
  • 58
  • 87
J-Bossi
  • 542
  • 6
  • 12
13

Updated Samson's answer because it would crash when I left the screen. Checked to make sure it was not nil before setting the constraint.

-(void) didMoveToWindow{
    [super didMoveToWindow];
    if (@available(iOS 11.0, *)) {

        UILayoutGuide *layoutGuide = self.window.safeAreaLayoutGuide;

        if (layoutGuide != nil){
           [[self bottomAnchor] constraintLessThanOrEqualToSystemSpacingBelowAnchor:layoutGuide.bottomAnchor multiplier:1.0].active = YES;
        }

    }
}
dmathewwws
  • 271
  • 2
  • 12
8

Guys I am the one asking jsqmessageviewcontroller ios11 toolbar and I have figured it out!

Just put the following code in the JSQMessagesInputToolbar.m. It seems that the inputtoolbar is placed in its own window, you need to access its window separately.

-(void) didMoveToWindow{
[super didMoveToWindow];
 if (@available(iOS 11.0, *)) {
     [[self bottomAnchor] constraintLessThanOrEqualToSystemSpacingBelowAnchor:self.window.safeAreaLayoutGuide.bottomAnchor multiplier:1.0].active = YES;
     }
}
Samson Wong
  • 226
  • 2
  • 10
  • 1
    Thanks, Samson Wong! That worked for me. Although, there is a bunch of logs about breaking the constraints. Also, I had a null pointer error when I was exiting the chat view. It turned out that self.window.safeAreaLayoutGuide was nil in exiting the view. So just put an If statement checking if it's nil. – Sami Ali Oct 25 '17 at 09:57
  • please mark it as solution if it solves the question :) – Samson Wong Oct 25 '17 at 10:17
5

I think this is should be a better way to solve this problem by following steps:
1. Open JSQMessagesViewController.xib
2. Drag down the collection view's bottom layout constraint into JSQMessagesViewController.m named collectionViewBottomLayoutGuide.
3. Add this code to the bottom of JSQMessagesViewController.m.

- (void)viewSafeAreaInsetsDidChange {
    [super viewSafeAreaInsetsDidChange];
    self.toolbarBottomLayoutGuide.active = NO;
    self.toolbarBottomLayoutGuide = [NSLayoutConstraint constraintWithItem:self.view.safeAreaLayoutGuide attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.inputToolbar attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];
    self.toolbarBottomLayoutGuide.active = YES;
    self.collectionViewBottomLayoutGuide.active = NO;
    self.collectionViewBottomLayoutGuide = [NSLayoutConstraint constraintWithItem:self.view.safeAreaLayoutGuide attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.collectionView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];
    self.collectionViewBottomLayoutGuide.active = YES;
}
Rabbit Zhou
  • 123
  • 1
  • 8
3

Adding a new constraint and leaving the old constraint which will lead to see the layout errors in xcode debug screen and xcode will break one of the constraint to be able to satisfy the layout. Even if you see the correct layout on the screen you may have different problems like not responding to the keyboard changes.

This may be solved better by changing the old constraint by following steps:

  1. Open JSQMessagesViewController.xib
  2. Click File Inspector and choose "Use safe area layout guides"
  3. Change deployment target of JSQMessagesViewController to 9.0
  4. Change first item of the Input toolbar's bottom constraint from Superview to Safe Area and constant to 0
  5. Run your project.
Alpha
  • 61
  • 4
  • Definitely, that would be the better approach but when I tried it the toolbar wouldn't move up with the keyboard. Has it worked for you? – Sami Ali Nov 24 '17 at 09:40
  • Very nice solution! Worked for me. Thanks buddy. @SamiAli you should first drag the toolbar a little bit up then set it's bottom constraint to safe area. – Suhail Nov 13 '20 at 10:20
2

Slight improvement of @J-Bossi's answer, for those of us who can't deal with autolayout technically breaking...

Just removes the existing constraint first, then adds that new constraint

extension JSQMessagesInputToolbar {
    override open func didMoveToWindow() {
        super.didMoveToWindow()
        guard let window = window else { return }
        if #available(iOS 11.0, *) {
            guard let constraint = (superview?.constraints.first { $0.secondAnchor == bottomAnchor }) else { return }
            let anchor = window.safeAreaLayoutGuide.bottomAnchor
            NSLayoutConstraint.deactivate([constraint])
            bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow(anchor, multiplier: 1.0).isActive = true
        }
    }
}
MQLN
  • 2,292
  • 2
  • 18
  • 33