3D Touch Peek in transform-inverted table view cell

291 Views Asked by At

I have a chat application where I am using the inverted table view technique (table view is scaled to (1, -1) with a transform, and all the cells themselves are scale to (1, -1) as well, neutralizing the effect, thus effectively inverting the table view to display the "first" cell at the bottom) to "start" the table view from bottom. Everything works fine, except that I need to implement peek and pop gesture. I've connected a button inside my table view cell to the target view controller, and enabled peek and pop as shown:

enter image description here

The gesture works, though when I 3D touch partially and hold enough to stand out the touched item (but not pop the preview view controller) I am getting inverted view:

enter image description here

How can I make the view pop out with correct transform, while still using the inverted table view?

1

There are 1 best solutions below

6
levidhuyvetter On

The reason why it shows the view upside down after a light press is not because it removes the transform from the cell. In fact the transform on the cell stays as it is but the segue pulls the cell view out of the context of the tableView. Therefore the transform on the cell is not counteracted by the transform on the table anymore.

I believe you could fix this by subclassing UIStoryboardSegue but it would probably be much easier to switch your method of starting the table at the bottom. Check out the accepted answer on this question.

I used a slightly modified version which accounts for the navigation bar and status bar:

func updateTableContentInset() {
    let numRows = tableView(self.tableView, numberOfRowsInSection: 0)
    var contentInsetTop = self.tableView.bounds.size.height - (self.navigationController?.navigationBar.frame.size.height)! - 20
    for i in 0..<numRows {
        let rowRect = self.tableView.rectForRow(at: IndexPath(item: i, section: 0))
        contentInsetTop -= rowRect.size.height
        if contentInsetTop <= 0 {
            contentInsetTop = 0
        }
    }
    self.tableView.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0)
}

Just add this to your UITableViewController and call it on viewDidLoad() and every time a new row is added to the table.

After adding a new row and then calling updateTableContentInset() you will have to scroll to the bottom like this:

tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)

Since there is nothing upside down here you will not have problems with your Peek segue.