Jsqmessageviewcontroller ios11 toolbar

I tried a quick example of JSQMessageViewController inside the iOS 11 simulator. Here is the result: screenshot

I tried to use the safe area of ​​the field and change the limit of the toolbar, but still no difference. The toolbar seems to be outside of UIWindow (instead of UITextEffectsWindow). Is there any solution?

+5
source share
6 answers
Guys, I get it! Just enter the following code in 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; } } 
+3
source

This answer is based on JSQMessagesViewController version 7.3.

Note. The code below contains some dirty pragma directives to avoid compiler warnings. The code itself is actually quite simple if you see outside the pragma.

This seems to solve the problem, while retaining the ability to move the toolbar when displaying the soft keyboard. I added the following code to my subclass of JSQMessagesViewController:

 - (void)viewDidLoad { [...] // To keep the toolbar inside the safe area on iPhone X, we need to install a new constraint that has higher priority than the one // JSQMessagesViewController manipulates when adjusting for the keyboard. The `toolbarBottomLayoutGuide` is a private property in our // superclass, so it not straightforward to access it... if (@available(iOS 11.0, *)) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" NSLayoutConstraint *constraint = [self performSelector:@selector(toolbarBottomLayoutGuide)]; #pragma clang diagnostic pop constraint.priority = 999; [self.inputToolbar.bottomAnchor constraintLessThanOrEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor].active = YES; } 

Edit: For Swift users, the following trick should allow you to call the objc private method:

 let constraint = perform(Selector(("toolbarBottomLayoutGuide"))).takeUnretainedValue() as! NSLayoutConstraint constraint.priority = 999 

Edit:. Code that customizes the content. Entering the contents of the collection is not called after adding this new restriction, therefore, if the chat window contains more messages than fits the screen, the last message bubble is hidden using the input toolbar. I solved this by making sure the inserts are updated by adding the following code to viewDidAppear viewDidLayoutSubviews:

 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" [self performSelector:@selector(jsq_updateCollectionViewInsets)]; #pragma clang diagnostic pop 
+3
source

Just add extension for JSQMessagesInputToolbar

 extension JSQMessagesInputToolbar { override open func didMoveToWindow() { super.didMoveToWindow() if #available(iOS 11.0, *), let window = self.window { let anchor = window.safeAreaLayoutGuide.bottomAnchor bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow(anchor, multiplier: 1.0).isActive = true } } } 
+3
source

Found a solution without empty space under the input toolbar on iPhoneX, the idea that not all the self toolbar should be above the safe area, but only its self.contentView :

 -(void) didMoveToWindow{ [super didMoveToWindow]; if (@available(iOS 11.0, *)) { if (self.window.safeAreaLayoutGuide != nil) { [[self.contentView bottomAnchor] constraintLessThanOrEqualToSystemSpacingBelowAnchor:self.window.safeAreaLayoutGuide.bottomAnchor multiplier:1.0].active = YES; } } } 
+2
source

I have the same problem. I am trying to solve this problem by adding a JSQMessageViewController as a child view on a viewController that has a safe zone.

Being MyJSQMessageViewController, a subclass of JSQMessagesViewController:

 self.myJSQMessageViewController = [[MyJSQMessageViewController alloc] init]; [self addChildViewController:self.myJSQMessageViewController]; [self.view addSubview:self.myJSQMessageViewController.view]; [self.myJSQMessageViewController didMoveToParentViewController:self]; if (@available(iOS 11.0, *)) { self.myJSQMessageViewController.view.translatesAutoresizingMaskIntoConstraints = NO; [NSLayoutConstraint activateConstraints:@[ [self.myJSQMessageViewController.view.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor], [self.myJSQMessageViewController.view.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor], [self.myJSQMessageViewController.view.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], [self.myJSQMessageViewController.view.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor] ]]; } constraintEqualToAnchor: self.view.safeAreaLayoutGuide.leadingAnchor], [self.myJSQMessageViewController.view.trailingAnchor constraintEqualToAnchor: self.view.safeAreaLayoutGuide.trailingAnchor], [self.myJSQMessageViewController.view self.myJSQMessageViewController = [[MyJSQMessageViewController alloc] init]; [self addChildViewController:self.myJSQMessageViewController]; [self.view addSubview:self.myJSQMessageViewController.view]; [self.myJSQMessageViewController didMoveToParentViewController:self]; if (@available(iOS 11.0, *)) { self.myJSQMessageViewController.view.translatesAutoresizingMaskIntoConstraints = NO; [NSLayoutConstraint activateConstraints:@[ [self.myJSQMessageViewController.view.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor], [self.myJSQMessageViewController.view.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor], [self.myJSQMessageViewController.view.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], [self.myJSQMessageViewController.view.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor] ]]; } 

Not an ideal solution, but at least you will have an input toolbar inside the iOS11 safe zone ... The bad news is that the input toolbar will not appear in unsafe areas, so it will not graphically look like the default toolbar (see . Image).

enter image description here

+1
source

I suggest a fixed fork based on the last completion of the develop JSQ branch.

Uses the didMoveToWindow solution. Not perfect, but worth a try, waiting for Apple's answer about the inputAccessoryView application of a safe area planning guide or any other better fix.

You can add this to your subfile by replacing the previous JSQ line:

 pod 'JSQMessagesViewController', :git => 'https://github.com/Tulleb/JSQMessagesViewController.git', :branch => 'develop', :inhibit_warnings => true 
+1
source

Source: https://habr.com/ru/post/1272144/


All Articles