Tuesday, 22 January 2019

TableView collapsing cell while scrolling to another: weird behavior

I have a tableView with chat bubbles.


Those bubbles are shortened if the character count is more than 250

If a user clicks on a bubble

  • The previous selection gets deselected (shortened)
  • The new selection expands and reveals the whole content
  • The new selections top constraint changes (from 0 to 4)

What I would like to achieve?

If a long bubble is selected already, but the user selects another bubble, I want the tableView to scroll to the position of the new selected bubble.

I'll share a video about it

Without this scrolling, the contentOffset remains the same and it looks bad.

(In the video: on the right)


Video:

Right: without the mentioned scrolling

Left: with scrolling

https://youtu.be/_-peZycZEAE


Here comes the problem:

On the left, you can notice that it is glitchy.

  • Random ghost cells are appearing for no reason.

  • Sometimes it even messes up the height of some bubbles (not in the video)

Why is it so?

Code:

func bubbleTappedHandler(sender: UITapGestureRecognizer) {

        let touchPoint = sender.location(in: self.tableView)
        if let indexPath = tableView.indexPathForRow(at: touchPoint) {

            if indexPath == currentSelectedIndexPath {

                // Selected bubble is tapped, deselect it
                self.selectDeselectBubbles(deselect: indexPath)

            } else {
                if (currentSelectedIndexPath != nil){

                    // Deselect old bubble, select new one
                    self.selectDeselectBubbles(select: indexPath, deselect: currentSelectedIndexPath)

                } else {

                    // Select bubble
                    self.selectDeselectBubbles(select: indexPath)

                }
            }

        }
    }



    func selectDeselectBubbles(select: IndexPath? = nil, deselect: IndexPath? = nil){


        var deselectCell : WorldMessageCell?
        var selectCell : WorldMessageCell?

        if let deselect = deselect {
            deselectCell = tableView.cellForRow(at: deselect) as? WorldMessageCell
        }
        if let select = select {
            selectCell = tableView.cellForRow(at: select) as? WorldMessageCell
        }


        // Deselect Main
        if let deselect = deselect, let deselectCell = deselectCell {

            tableView.deselectRow(at: deselect, animated: false)
            currentSelectedIndexPath = nil
            // Update text
            deselectCell.messageLabel.text = self.dataSource[deselect.row].message.shortened()


        }
        // Select Main
        if let select = select, let selectCell = selectCell {

            tableView.selectRow(at: select, animated: true, scrollPosition: .none)
            currentSelectedIndexPath = select
            // Update text
            deselectCell.messageLabel.text = self.dataSource[select.row].message.full()
        }


        UIView.animate(withDuration: appSettings.defaultAnimationSpeed) {

            // Deselect Constraint changes

            if let deselect = deselect, let deselectCell = deselectCell {
                // Constarint change
                deselectCell.nickNameButtonTopConstraint.constant = 0
                deselectCell.timeLabel.alpha = 0.0
                deselectCell.layoutIfNeeded()

            }

            // Select Constraint changes
            if let select = select, let selectCell = selectCell {

                // Constarint change
                selectCell.nickNameButtonTopConstraint.constant = 4
                selectCell.timeLabel.alpha = 1.0
                selectCell.layoutIfNeeded()


            }


        }

        self.tableView.beginUpdates()
        self.tableView.endUpdates()



        UIView.animate(withDuration: appSettings.defaultAnimationSpeed) {
            if let select = select, deselect != nil, self.tableView.cellForRow(at: deselect!) == nil && deselectCell != nil {

                // If deselected row is not anymore on screen
                // but was before the collapsing,
                // then scroll to new selected row  

                self.tableView.scrollToRow(at: select, at: .top, animated: false)
            }
        }

    }


Update 1: Added Github project

Link: https://github.com/krptia/test2

I made a small version of my app, so that you can see and test what my problem is. I would be so thankful if someone could help to solve this issue! :c



from TableView collapsing cell while scrolling to another: weird behavior

No comments:

Post a Comment