Ioni c Положение прокрутки в iOS - PullRequest
0 голосов
/ 25 апреля 2020

Я создаю простое приложение для чата, и у меня возникла проблема с настройкой положения прокрутки в iOS. Кажется, он отлично работает на других платформах, включая браузер. Ioni c v5, с использованием Capacitor, сборка с Appflow.

Контейнер должен быть прокручен по умолчанию при загрузке данных. Затем страница прослушивает новые сообщения. Если добавляется новое сообщение, то страница должна прокручиваться вниз, если позиция прокрутки находится в пределах нижних 150% высоты клиента. Если нет, появляется FAB, указывающий, что появилось новое сообщение, и пользователь может выбрать кнопку для прокрутки до кнопки.

Разметка такая же. У меня есть специальная директива domChange, которая прослушивает изменения dom в div. Я предпочитаю размещать логи прокрутки c здесь, так как я испытывал ошибки, помещая его в прослушиватель сообщений ранее.

<ion-content>
  <div class="chat-container" (click)="containerClick();" (scroll)="scroll($event)" #chatContainer>
    <div class="wrapper" *ngIf="messages.length > 0" (domChange)="onDomChange($event)">
      <!-- Excuse my inline styling, this is just for debug -->
      <div style="width:100%;text-align:center;padding:20px;" *ngIf="loadingMore"><ion-spinner></ion-spinner></div>
      <ng-container *ngFor="let message of messages">
        <chat-bubble
        [sent]="message.from === authService.user.id"
        [delivered]="message.delivered"
        [position]="message.position"
        [timestamp]="message.createdAt.getTime()"
        [content]="message.content"
        >
        </chat-bubble>
      </ng-container>
    </div>
  </div>
  <ion-fab vertical="bottom" horizontal="center" slot="fixed" *ngIf="showScrollBtn">
    <ion-fab-button size="small" (click)="scrollToBottom()"><ion-icon name="arrow-down-outline"></ion-icon></ion-fab-button>
  </ion-fab>
</ion-content>

CSS относительно прост, но я использую flexbox с обратным столбцом и Я думаю, что это может быть одной из причин этой проблемы. Обратный столбец означает, что веб-просмотр по умолчанию отображает прокрутку внизу.

.chat-container {
  height: 100%;
  flex-grow: 1;
  overflow: auto;
  display: flex;
  flex-direction: column-reverse;
  overflow-x: hidden;
  padding: 0 16px 0 16px;
}

А затем соответствующие функции:

  public onDomChange(event: any) {
    if(event.addedNodes.length > 0 && event.addedNodes[0].localName == 'chat-bubble') {
      const scrollTop = (this.platform.is('ios') && !this.platform.is('mobileweb')) ? this.chatContainer.nativeElement.scrollTop + this.chatContainer.nativeElement.scrollHeight : this.chatContainer.nativeElement.scrollTop;
      /*
       * Because of the column-reverse iOS sees the bottom of the div as scrollTop = 0 and the top of the div as scrollTop = -scrollHeight
       * Android sees it as scrollTop = scrollHeight at the bottom and scrollTop = 0 at the top
      */
      const scrollHeight = this.chatContainer.nativeElement.scrollHeight;
      const clientHeight = this.chatContainer.nativeElement.clientHeight * 1.5;

      const newMessageIndex = this.messages[this.messages.length - 1].index;

      if((this.messages.length <= 30 || scrollHeight - scrollTop <= clientHeight) && this.channel.lastConsumedMessageIndex < newMessageIndex) {
        this.scrollToBottom();
      } else if(this.channel.lastConsumedMessageIndex < newMessageIndex) {
        this.showScrollBtn = true;
      }
    }
  }
  public scrollToBottom(): Promise<any> {
    this.showScrollBtn = false;
    this.chatContainer.nativeElement.scrollTop = this.chatContainer.nativeElement.scrollHeight;
    return this.channel.setAllMessagesConsumed();
  }

Функция scrollToBottom() работает абсолютно нормально, когда запускается событием нажатия кнопки, но, похоже, ничего не делает, когда срабатывает в триггере domChange. Я думаю, это потому, что триггер вызывается до того, как элемент пузыря чата рендерится, но я не уверен, как это исправить.

Буду признателен за любые идеи / мысли

Заранее спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...