0

I'm making simple chat application, so when users taps on specific chat in chat list he must go to last message in this specific chat room (like in Telegram). I tried to create own scrollToBottom function:

func scrollToBottom(animated animated: Bool) {

    if self.collectionView.numberOfSections() == 0 {
        return
    }

    if self.collectionView.numberOfItemsInSection(0) == 0 {
        return
    }

    let collectionViewContentHeight = self.collectionView.collectionViewLayout.collectionViewContentSize().height
    let isContentTooSmall = collectionViewContentHeight < CGRectGetHeight(self.collectionView.bounds)

    if isContentTooSmall {

        self.collectionView.scrollRectToVisible(CGRectMake(0, collectionViewContentHeight - 1, 1, 1), animated: animated)
        return
    }

    let finalRow = max(0, self.collectionView.numberOfItemsInSection(0) - 1)
    let finalIndexPath = NSIndexPath(forRow: finalRow, inSection: 0)
    let finalCellSize = self.collectionView.messagesCollectionViewLayout.sizeForItem(finalIndexPath)

    let maxHeightForVisibleMessage = self.collectionView.bounds.height - self.collectionView.contentInset.top
    let scrollPosition: UICollectionViewScrollPosition = finalCellSize.height > maxHeightForVisibleMessage ? .Bottom : .Top

    self.collectionView.scrollToItemAtIndexPath(finalIndexPath, atScrollPosition: scrollPosition, animated: animated)
}

But when i call it in viewWillAppear i get small delay before it jumps to last row of the chat room, which is not good. Please help!

pavel_s
  • 465
  • 1
  • 7
  • 27
  • How many messages are you fetching/showing from DB at once? – Bista Jan 13 '16 at 09:45
  • try this one [self.collectionView scrollToRowAtIndexPath: [NSIndexPath indexPathForRow: finalRow inSection: 0] atScrollPosition: UICollectionViewScrollPositionBottom animated: YES]; – Avaan Jan 13 '16 at 09:56
  • the_UB, it depends, about 50-100 messages – pavel_s Jan 13 '16 at 13:42

3 Answers3

1

viewWillAppear will be called after viewDidLoad. If you need to call this method once your viewcontroller is launched, then you can add the code in the viewDidload method. But if you still need to use viewWillAppear, I suggest to wrap this call on the main thread or mainqueue. You can use GCD or NSOperationQueue for this.

I think this might help in the delay issue

Sabby
  • 2,586
  • 2
  • 27
  • 41
0

If the chat messages are rendered on UITableView , use a function

    self.tableView scrollToRowAtIndexPath:<#(nonnull NSIndexPath *)#> atScrollPosition:<#(UITableViewScrollPosition)#> animated:<#(BOOL)#>

This method will move content with good animation.

AskIOS
  • 918
  • 7
  • 19
0

Thanks to @Sabby, i add this code to viewWillAppear, and somehow it worked

    let delayTime = dispatch_time(DISPATCH_TIME_NOW, 0)
    dispatch_after(delayTime,dispatch_get_main_queue()) {
        self.collectionView.contentInset.bottom = 40.0
        self.scrollToBottom(animated: false)
    }
pavel_s
  • 465
  • 1
  • 7
  • 27