5

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?

Lal Krishna
  • 15,485
  • 6
  • 64
  • 84
Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389

1 Answers1

2

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.

levidhuyvetter
  • 401
  • 5
  • 16
  • For many reasons, I can't change the "inverted transform" behavior of the table view. Any examples on how I can do it with the custom segue class? – Can Poyrazoğlu Apr 08 '18 at 13:55
  • If you log when a segue starts you can see that Apple uses 2 segues. One starts when you light press the second starts when the preview pops to full view. I’m not sure if it is possible and if it is then it would be extremely involved. You would have to turn off peek and pop in IB and create your own segue from scratch that transforms the views depending on how hard the screen is pressed. – levidhuyvetter Apr 08 '18 at 14:15
  • Basically you will be recreating what apple has already made with the only difference it doesn't flip a cell. The inverted table was kind of a hack to begin with so even if you have to change you design to fit the above solution it will still be easier than a custom segue. Plus you will have a cleaner way of starting your table at the bottom which will prevent issues in the future, for example if a software update breaks the inverted table hack. – levidhuyvetter Apr 08 '18 at 14:18
  • I agree with you inverted table view being an ugly hack, though all of my coworkers are using it everywhere (it caused many trouble on chat screens especially with dynamic keyboard heights and smooth insertion animations) so I don't think it would be good to change at this point since we're sharing the code base :( If it was a personal project I'd go with changing it but at this point, it doesn't seem possible since other people are also involved. – Can Poyrazoğlu Apr 08 '18 at 14:41
  • Fair enough. Unfortunately I won’t be able to do any more than sending you in the right direction in regards to the custom segue. I would do some experiments with normal custom segues and then some with getting data from screen pressure and try to combine them somehow. – levidhuyvetter Apr 08 '18 at 14:59
  • I'll be looking into the custom segues – Can Poyrazoğlu Apr 08 '18 at 15:34