As soon as the cell is no longer visible on the screen I need to be notified.
一旦单元格不在屏幕上,我就需要被通知。
UITableView already has a delegate method called tableView:didEndDisplayingCell:forRowAtIndexPath:
but this delegate method never gets called. And yes I do have the delegate for my UITableView set.
UITableView已经有一个名为tableView:didEndDisplayingCell:forRowAtIndexPath:的委托方法,但是这个委托方法不会被调用。是的,我有UITableView集合的委托。
Any other ways to detect a cell being removed? I need to be able to save the content (inputs) of this cell before it's being reused by another item.
还有其他检测被移除的单元格的方法吗?我需要能够保存这个单元格的内容(输入),然后才能被其他项重用。
EDIT:
编辑:
According to the documentation tableView:didEndDisplayingCell:forRowAtIndexPath:
is iOS 6 and higher API. Is there a way to achieve this on iOS 5?
根据文档表视图:didEndDisplayingCell:forRowAtIndexPath: is ios6和更高的API。在ios5上有实现这一点的方法吗?
3 个解决方案
#1
8
On versions of iOS older than 6.0, the table view doesn't send the tableView:didEndDisplayingCell:forRowAtIndexPath:
message.
对于大于6.0的iOS版本,表视图不会发送tableView:didEndDisplayingCell:forRowAtIndexPath: message。
If you are using a subclass of UITableViewCell
, you can get the same effect on older versions of iOS by overriding didMoveToWindow
:
如果你正在使用UITableViewCell的子类,你可以通过覆盖didMoveToWindow来获得对旧版本iOS的相同影响:
- (void)didMoveToWindow {
if (self.window == nil) {
// I have been removed from the table view.
}
}
You may need to give your cell a (weak or unsafe_unretained) reference back to your table view delegate so you can send the delegate a message.
您可能需要将一个(弱的或unsafe_unretain的)引用返回给您的表视图委托,以便您可以向委托发送一条消息。
However, you can't rely only on didMoveToWindow
for all versions of iOS. Before iOS 6, a table view always removed a table view cell as a subview before reusing it, so the cell would always receive didMoveToWindow
before being reused. However, starting in iOS 6, a table view can reuse a cell without removing it as a subview. The table view will simply change the cell's frame to move it to its new location. This means that starting in iOS 6, a cell does not always receive didMoveToWindow
before being reused.
然而,你不能仅仅依靠didMoveToWindow来实现iOS的所有版本。在ios6之前,表视图总是在重用表视图单元之前将其作为子视图删除,因此在重用它之前,该单元始终会接收didMoveToWindow。但是,从ios6开始,表视图可以重用单元格,而不必将其作为子视图删除。表视图将简单地更改单元格的框架,将其移动到新位置。这意味着从iOS 6开始,单元格在被重用之前并不总是接收didMoveToWindow。
So you should implement both didMoveToWindow
in your cell subclass, and tableView:didEndDisplayingCell:forRowAtIndexPath:
in your delegate, and make sure it works if both are called, or if just one is called.
因此,您应该在单元格子类中实现didMoveToWindow,并在委托中实现tableView:didEndDisplayingCell:forRowAtIndexPath:,如果调用了这两个类,或者只调用了一个类,则确保它能够工作。
#2
4
I ended up using the combination of below to make sure that the logic applies to both iOS 5.0 and 6.0
我最后使用了下面的组合来确保逻辑同时适用于iOS 5.0和6.0
CELL LOGIC
细胞逻辑
@protocol MyCellDelegate
- (void)myCellDidEndDisplaying:(MyCell *)cell;
@end
@implementation MyCell
// Does not work on iOS 6.0
- (void)removeFromSuperview
{
[super removeFromSuperview];
[self.delegate myCellDidEndDisplaying:(MyCell *)self];
}
@end
VIEWCONTROLLER LOGIC
VIEWCONTROLLER逻辑
@implementation MyViewcontroller
- (void)myCellDidEndDisplaying:(MyCell *)cell
{
IndexPath *indexPath = [self.tableView indexPatForCell:cell];
// do stuff
}
// Does not work on iOS below 6.0
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
}
@end
#3
1
tableView:didEndDisplayingCell:forRowAtIndexPath:
is only available in iOS6 and later.
只能在iOS6和以后的版本中使用。
One (albeit slow) way to accomplish what you are after would be to use the scrollView delegate methods to monitor when the tableview scrolls. From there, call:
实现您所追求的目标的一种方法(尽管很慢)是使用scrollView委托方法来监视tableview何时滚动。从那里,电话:
NSArray *visiblePaths = [tableView indexPathsForVisibleRows];
and check for any changes to the array of visible paths.
并检查对可见路径数组的任何更改。
#1
8
On versions of iOS older than 6.0, the table view doesn't send the tableView:didEndDisplayingCell:forRowAtIndexPath:
message.
对于大于6.0的iOS版本,表视图不会发送tableView:didEndDisplayingCell:forRowAtIndexPath: message。
If you are using a subclass of UITableViewCell
, you can get the same effect on older versions of iOS by overriding didMoveToWindow
:
如果你正在使用UITableViewCell的子类,你可以通过覆盖didMoveToWindow来获得对旧版本iOS的相同影响:
- (void)didMoveToWindow {
if (self.window == nil) {
// I have been removed from the table view.
}
}
You may need to give your cell a (weak or unsafe_unretained) reference back to your table view delegate so you can send the delegate a message.
您可能需要将一个(弱的或unsafe_unretain的)引用返回给您的表视图委托,以便您可以向委托发送一条消息。
However, you can't rely only on didMoveToWindow
for all versions of iOS. Before iOS 6, a table view always removed a table view cell as a subview before reusing it, so the cell would always receive didMoveToWindow
before being reused. However, starting in iOS 6, a table view can reuse a cell without removing it as a subview. The table view will simply change the cell's frame to move it to its new location. This means that starting in iOS 6, a cell does not always receive didMoveToWindow
before being reused.
然而,你不能仅仅依靠didMoveToWindow来实现iOS的所有版本。在ios6之前,表视图总是在重用表视图单元之前将其作为子视图删除,因此在重用它之前,该单元始终会接收didMoveToWindow。但是,从ios6开始,表视图可以重用单元格,而不必将其作为子视图删除。表视图将简单地更改单元格的框架,将其移动到新位置。这意味着从iOS 6开始,单元格在被重用之前并不总是接收didMoveToWindow。
So you should implement both didMoveToWindow
in your cell subclass, and tableView:didEndDisplayingCell:forRowAtIndexPath:
in your delegate, and make sure it works if both are called, or if just one is called.
因此,您应该在单元格子类中实现didMoveToWindow,并在委托中实现tableView:didEndDisplayingCell:forRowAtIndexPath:,如果调用了这两个类,或者只调用了一个类,则确保它能够工作。
#2
4
I ended up using the combination of below to make sure that the logic applies to both iOS 5.0 and 6.0
我最后使用了下面的组合来确保逻辑同时适用于iOS 5.0和6.0
CELL LOGIC
细胞逻辑
@protocol MyCellDelegate
- (void)myCellDidEndDisplaying:(MyCell *)cell;
@end
@implementation MyCell
// Does not work on iOS 6.0
- (void)removeFromSuperview
{
[super removeFromSuperview];
[self.delegate myCellDidEndDisplaying:(MyCell *)self];
}
@end
VIEWCONTROLLER LOGIC
VIEWCONTROLLER逻辑
@implementation MyViewcontroller
- (void)myCellDidEndDisplaying:(MyCell *)cell
{
IndexPath *indexPath = [self.tableView indexPatForCell:cell];
// do stuff
}
// Does not work on iOS below 6.0
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
}
@end
#3
1
tableView:didEndDisplayingCell:forRowAtIndexPath:
is only available in iOS6 and later.
只能在iOS6和以后的版本中使用。
One (albeit slow) way to accomplish what you are after would be to use the scrollView delegate methods to monitor when the tableview scrolls. From there, call:
实现您所追求的目标的一种方法(尽管很慢)是使用scrollView委托方法来监视tableview何时滚动。从那里,电话:
NSArray *visiblePaths = [tableView indexPathsForVisibleRows];
and check for any changes to the array of visible paths.
并检查对可见路径数组的任何更改。