jsqmessageviewcontroller панель инструментов ios11

Я попробовал быстрый пример JSQMessageViewController внутри симулятора iOS 11. Вот результат: скриншот

Я попытался использовать безопасную область поля и изменить ограничение панели инструментов, но до сих пор нет никакой разницы. Кажется, что панель инструментов находится за пределами UIWindow (вместо этого UITextEffectsWindow). Есть ли решение?

6 ответов

Решение

Ребята я разобрался! Просто поместите следующий код в JSQMessagesInputToolbar.m. Кажется, что inputtoolbar находится в своем собственном окне, вам нужно получить доступ к его окну отдельно.

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

Просто добавьте расширение для 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
        }
    }
}

Я предлагаю фиксированный форк на основе последней JSQ develop ветвь коммит.

Это использует didMoveToWindow решение. Не идеально, но стоит попробовать, ожидая ответа Apple о inputAccessoryViewбезопасное расположение направляющих вложения, или любое другое лучшее исправление.

Вы можете добавить это в ваш Podfile, заменив предыдущую строку JSQ:

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

Этот ответ основан на версии 7.3 JSQMessagesViewController.

Примечание. Приведенный ниже код содержит некоторые грязные прагматические директивы, позволяющие избежать предупреждений компилятора. Сам код на самом деле довольно прост, когда вы видите за пределами прагм.

Это, кажется, решает проблему, в то же время позволяя перемещать панель инструментов, когда представлена ​​программная клавиатура. Я добавил следующий код в мой подкласс 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

Редактировать: код, который корректирует contentInset коллекции collectionView, не вызывается после добавления этого нового ограничения, поэтому, если представление чата содержит больше сообщений, чем умещается на экране, последний пузырь сообщения скрывается панелью инструментов ввода. Я решил это, обновив вставки, добавив следующий код в viewDidAppear viewDidLayoutSubviews:

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

У меня такая же проблема. Я пытаюсь решить эту проблему, добавив 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... Плохая новость заключается в том, что панель инструментов ввода не будет отображаться в небезопасных областях, поэтому графически она не будет похожа на панель инструментов по умолчанию (см. Изображение)

Нашел решение без пустого места под панелью инструментов ввода на iPhoneX, идея о том, что не вся панель инструментов должна быть выше безопасной области, а только ее содержимое:

-(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;
        }
    }
}

Check this response:

Which state:

  • Create an interface of JSQMessagesInputToolbar class, and
  • Override didMoveToWindow method to add this code:

    - (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;
            }
        }
    }
    

Note: Creating interface is preferred over changing the class. Because if you used cocoa pods then each time you updated pods your changes will be overwritten.

I have checked it with iPhone XR (Simulator) and iPhone 7 (Device) it works fine.

Для тех, у кого есть проблемы с панелью инструментов даже после применения didMoveToWindowисправить, это может быть связано с IQKeyboardManager.

С IQKeyboardManager у меня возникли некоторые проблемы при прокрутке вниз (скрытие клавиатуры) или касании "вступления", поэтому лучше отключить его для того конкретного ViewController, где находится чат. Таким образом, внизу не будет нежелательного поля.

Другие вопросы по тегам