jsqmessageviewcontroller ios11 工具栏
jsqmessageviewcontroller ios11 toolbar
我已经在 iOS 11 模拟器中尝试了 JSQMessageViewController
的 swift 示例。这是结果:screenshot
我尝试过使用安全区域边距并修改工具栏约束,但仍然没有区别。看起来工具栏在 UIWindow 之外(而不是 UITextEffectsWindow)。有什么解决办法吗?
我遇到了同样的问题。我试图通过将 JSQMessageViewController 添加为已设置安全区域的 viewController 的子视图来解决它。
MyJSQMessageViewController 是 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] ]];
}
不是理想的解决方案,但至少您将在 iOS11 安全区域中拥有输入工具栏...
坏消息是输入工具栏不会显示在非安全区域,因此图形上不会像默认工具栏一样(见图)
本回答基于 JSQMessagesViewController 7.3 版本
注意:下面的代码包含一些杂乱的 pragma 指令以避免编译器警告。一旦您超越编译指示,代码本身实际上非常简单。
这似乎解决了问题,同时仍然允许在显示软件键盘时移动工具栏。我在我的 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's 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;
}
编辑: 对于 Swift 用户,以下技巧应该可以让您调用私有 objc 方法:
let constraint = perform(Selector(("toolbarBottomLayoutGuide"))).takeUnretainedValue() as! NSLayoutConstraint
constraint.priority = 999
编辑: 添加此新约束后不会调用调整 collectionView 的 contentInset 的代码,因此如果聊天视图包含的消息多于屏幕,最后一个消息气泡被输入工具栏遮住了。我通过在 viewDidAppear viewDidLayoutSubviews:
中添加以下代码来确保更新插图来解决这个问题
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
[self performSelector:@selector(jsq_updateCollectionViewInsets)];
#pragma clang diagnostic pop
伙计们,我想通了!只需将以下代码放在 JSQMessagesInputToolbar.m 中即可。好像inputtoolbar是放在自己的window里面的,需要单独访问它的window
-(void) didMoveToWindow{
[super didMoveToWindow];
if (@available(iOS 11.0, *)) {
[[self bottomAnchor] constraintLessThanOrEqualToSystemSpacingBelowAnchor:self.window.safeAreaLayoutGuide.bottomAnchor multiplier:1.0].active = YES;
}
}
我提议基于 JSQ 最新 develop
分支提交的固定分支。
它正在使用 didMoveToWindow
解决方案。不理想,但在等待 Apple 关于 inputAccessoryView
的安全区域布局指南附件或任何其他更好的修复的答案时值得尝试。
您可以将其添加到您的 Podfile 中,替换之前的 JSQ 行:
pod 'JSQMessagesViewController', :git => 'https://github.com/Tulleb/JSQMessagesViewController.git', :branch => 'develop', :inhibit_warnings => true
只需为 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
}
}
}
在 iPhoneX 的输入工具栏下面找到了没有空白 space 的解决方案,想法是不是整个工具栏 self
应该在安全区域上方,而只是它的 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;
}
}
}
检查这个 response:
哪个州:
- 创建
JSQMessagesInputToolbar
class和 的接口
覆盖 didMoveToWindow
方法以添加此代码:
- (void)didMoveToWindow {
[super didMoveToWindow];
NSLog(@"didMoveToWindow");
if (@available(iOS 11.0, *)) {
UILayoutGuide * _Nonnull safeArea = self.window.safeAreaLayoutGuide;
if (safeArea) {
NSLayoutYAxisAnchor * _Nonnull bottomAnchor = safeArea.bottomAnchor;
[[self bottomAnchor] constraintLessThanOrEqualToSystemSpacingBelowAnchor:bottomAnchor multiplier:1.0].active = YES;
}
}
}
注意: 创建界面优于更改 class。因为如果您使用 cocoa pods 那么每次更新 pods 您的更改都会被覆盖。
我已经用 iPhone XR(模拟器)和 iPhone 7(设备)检查过它工作正常。
对于即使在应用 didMoveToWindow
修复后工具栏仍存在问题的任何人,这可能是由于 IQKeyboardManager.
使用 IQKeyboardManager 时,我在向下滚动(隐藏键盘)或点击“介绍”时遇到了一些问题,因此最好在聊天所在的特定 ViewController 禁用它。这样,底部就不会出现多余的边距了。
我已经在 iOS 11 模拟器中尝试了 JSQMessageViewController
的 swift 示例。这是结果:screenshot
我尝试过使用安全区域边距并修改工具栏约束,但仍然没有区别。看起来工具栏在 UIWindow 之外(而不是 UITextEffectsWindow)。有什么解决办法吗?
我遇到了同样的问题。我试图通过将 JSQMessageViewController 添加为已设置安全区域的 viewController 的子视图来解决它。
MyJSQMessageViewController 是 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] ]];
}
不是理想的解决方案,但至少您将在 iOS11 安全区域中拥有输入工具栏... 坏消息是输入工具栏不会显示在非安全区域,因此图形上不会像默认工具栏一样(见图)
本回答基于 JSQMessagesViewController 7.3 版本
注意:下面的代码包含一些杂乱的 pragma 指令以避免编译器警告。一旦您超越编译指示,代码本身实际上非常简单。
这似乎解决了问题,同时仍然允许在显示软件键盘时移动工具栏。我在我的 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's 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;
}
编辑: 对于 Swift 用户,以下技巧应该可以让您调用私有 objc 方法:
let constraint = perform(Selector(("toolbarBottomLayoutGuide"))).takeUnretainedValue() as! NSLayoutConstraint
constraint.priority = 999
编辑: 添加此新约束后不会调用调整 collectionView 的 contentInset 的代码,因此如果聊天视图包含的消息多于屏幕,最后一个消息气泡被输入工具栏遮住了。我通过在 viewDidAppear viewDidLayoutSubviews:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
[self performSelector:@selector(jsq_updateCollectionViewInsets)];
#pragma clang diagnostic pop
伙计们,我想通了!只需将以下代码放在 JSQMessagesInputToolbar.m 中即可。好像inputtoolbar是放在自己的window里面的,需要单独访问它的window
-(void) didMoveToWindow{
[super didMoveToWindow];
if (@available(iOS 11.0, *)) {
[[self bottomAnchor] constraintLessThanOrEqualToSystemSpacingBelowAnchor:self.window.safeAreaLayoutGuide.bottomAnchor multiplier:1.0].active = YES;
}
}
我提议基于 JSQ 最新 develop
分支提交的固定分支。
它正在使用 didMoveToWindow
解决方案。不理想,但在等待 Apple 关于 inputAccessoryView
的安全区域布局指南附件或任何其他更好的修复的答案时值得尝试。
您可以将其添加到您的 Podfile 中,替换之前的 JSQ 行:
pod 'JSQMessagesViewController', :git => 'https://github.com/Tulleb/JSQMessagesViewController.git', :branch => 'develop', :inhibit_warnings => true
只需为 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
}
}
}
在 iPhoneX 的输入工具栏下面找到了没有空白 space 的解决方案,想法是不是整个工具栏 self
应该在安全区域上方,而只是它的 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;
}
}
}
检查这个 response:
哪个州:
- 创建
JSQMessagesInputToolbar
class和 的接口
覆盖
didMoveToWindow
方法以添加此代码:- (void)didMoveToWindow { [super didMoveToWindow]; NSLog(@"didMoveToWindow"); if (@available(iOS 11.0, *)) { UILayoutGuide * _Nonnull safeArea = self.window.safeAreaLayoutGuide; if (safeArea) { NSLayoutYAxisAnchor * _Nonnull bottomAnchor = safeArea.bottomAnchor; [[self bottomAnchor] constraintLessThanOrEqualToSystemSpacingBelowAnchor:bottomAnchor multiplier:1.0].active = YES; } } }
注意: 创建界面优于更改 class。因为如果您使用 cocoa pods 那么每次更新 pods 您的更改都会被覆盖。
我已经用 iPhone XR(模拟器)和 iPhone 7(设备)检查过它工作正常。
对于即使在应用 didMoveToWindow
修复后工具栏仍存在问题的任何人,这可能是由于 IQKeyboardManager.
使用 IQKeyboardManager 时,我在向下滚动(隐藏键盘)或点击“介绍”时遇到了一些问题,因此最好在聊天所在的特定 ViewController 禁用它。这样,底部就不会出现多余的边距了。