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:

哪个州:

  • 创建JSQMessagesInputToolbarclass和
  • 的接口
  • 覆盖 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 禁用它。这样,底部就不会出现多余的边距了。