7

I have a table with shadows above the top and below the bottom cell (using Matt Gallagher's solution here: http://cocoawithlove.com/2009/08/adding-shadow-effects-to-uitableview.html). These are added in the layoutSubviews method of the UITableView class extension.

I dynamically add and delete cells below each main cell (these provide additional data) - let's call these "detail" cells. There is only one ever open at a time. When deleting the "detail cell" beneath the last main cell, as the animation begins, the shadow flicks upwards to the last cell (above the detail cell). It does this because the layoutSubview methods considers the last cell of the table to have changed the moment the animation for deleteRowsAtIndexPaths begins (rather than when the animation ends).

So, in essence, I need a way to keep the shadow below the detail cell as its being deleted. Not sure of the best way to do this. If the UITableView no longer considers that cell to be the last cell, then I am not sure even how to get the cell (since the UITableView gets the cell thus):

NSIndexPath *lastRow = [indexPathsForVisibleRows lastObject];
if ([lastRow section] == [self numberOfSections] - 1 &&
    [lastRow row] == [self numberOfRowsInSection:[lastRow section]] - 1)
 {
        //adds shadow below it here
     }

So even trapping the start of the animation is not much use if the UITableView still thinks the main cell above the "detail" cell is the "lastObject".

Thanks for any ideas.

fezfox
  • 967
  • 9
  • 14
  • Have you tried adding the top and bottom shadow as `tableHeaderView` and `tableFooterView` respectively? Surely these views are kept in place and moved appropriately when the table resizes after a delete animation. – simeon Nov 16 '12 at 00:21

3 Answers3

7

Try this

[CATransaction begin];

[tableView beginUpdates];

//...

[CATransaction setCompletionBlock: ^{
    // Code to be executed upon completion
}];

[tableView deleteRowsAtIndexPaths: indexPaths
                 withRowAnimation: UITableViewRowAnimationAutomatic];


[tableView endUpdates];

[CATransaction commit];
Peter Lapisu
  • 19,915
  • 16
  • 123
  • 179
  • I needed to refresh the table after `deleteRowsAtIndexPaths:withRowAnimation` animation completed, this did it for me. Thanks! perhaps in 2015 there is a better way? – ToddB May 06 '15 at 16:44
0

I am sure that you can easily achieve this by using a custom table view class instead of using dependencies from external frame work just inherit from the uitable view and add subviews to it.

But if you insist to keep it this way. take a reference in your own variable before deleting it.

Prajwal Udupa
  • 860
  • 5
  • 28
  • Matt Gallager's shadowed table view **is** a custom table class... so what's your point? – fezfox Jan 26 '13 at 10:35
  • I mean to say that add sub views to that table view and in that subview add that gradient image. – Prajwal Udupa Jan 26 '13 at 14:23
  • Ok, thats a suggestion - but how do you propose where to place that view? The point I made in the OP is that the moment the animation to remove the final cell begins, [indexPathsForVisibleRows lastObject] will immediately reflect the row above. So if that is the reference you use to place your shadow (as it is at the moment) the moment the animation begins the shadow flicks upwards to the cell above. Perhaps the real thing to do is to stop the updating of that shadow until the animation is complete, OR the suggestion above, to use a tableFooterView instead. I gave up a year ago - thanks anyway – fezfox Jan 28 '13 at 02:34
  • Oh for that add the shadow view after each cell and make sure that the next cell overlaps the shadow of the previous cell in this way there is no shifting of shadow. the animation will also delete the shadow of the cell of the last cell. – Prajwal Udupa Jan 28 '13 at 06:06
  • You can achieve this by adjusting the height of each cell. – Prajwal Udupa Jan 28 '13 at 06:08
0

Swift (the idea is the same, you can of course use this in obj-c):

UIView.animateWithDuration(0.3, animations: { () -> Void in
    self.tableView.scrollToRowAtIndexPath(indexPathes, withRowAnimation: UITableViewRowAnimation.None)
}, completion: { (Bool) -> Void in
    // The logic you want to execute after the animation
})
Brian
  • 30,156
  • 15
  • 86
  • 87