情况:
我已经将 UITableViewCell 子类化,因为我需要在 UITableViewCell 的任一侧添加自定义操作按钮。在某些情况下,我需要将 UITableView 设置回正常状态(隐藏自定义操作按钮)。 例如 当用户在 UITableView 中向上滚动时。为此,我将我的自定义 UITableViewCell 添加为包含 UITableView 的 UIPangestureRecognizer 状态的观察者。
问题:
弹出包含 UITableView 和自定义 UITableViewCells 的 UIViewController 时,我收到以下错误:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x7b21b920 of class UIScrollViewPanGestureRecognizer was deallocated while key value observers were still registered with it. Current observation info: ( Context: 0xb83618, Property: 0x7b3e13b0> Context: 0xb83618, Property: 0x7b3e13b0> Context: 0xb83618, Property: 0x7b3e13b0> Context: 0xb83618, Property: 0x7b3e13b0> )'
这显然是说 UIPanGestureRecognizer 在自定义 UITableViewCell 之前被释放。
问题:
作为 UITableView 的 UIPanGestureRecognizer 的观察者,我应该在哪里删除自定义 UITableViewCell,这样我就不会遇到这个异常?
代码: (我希望这不是太多需要梳理的代码。如果是的话,我深表歉意。)
CustomUITableViewCell.m
#pragma mark - Setter Methods
- (void)setContainingTableView:(UITableView *)containingTableView
{
if (self.isObservingContainingTableViewPanGestureRecognizer)
{
self.observingContainingTableViewPanGestureRecognizer = NO;
[_containingTableView.panGestureRecognizer removeObserver:self forKeyPath:kUITableViewPanGestureRecognizerStateKeyPath];
}
_containingTableView = containingTableView;
if (containingTableView)
{
self.observingContainingTableViewPanGestureRecognizer = YES;
[containingTableView.panGestureRecognizer addObserver:self forKeyPath:kUITableViewPanGestureRecognizerStateKeyPath options:0 context:UITableViewPanGestureRecogonizerContext];
}
}
#pragma mark -
#pragma mark - Overrides
- (void)didMoveToSuperview
{
[super didMoveToSuperview];
self.containingTableView = nil;
UIView * view = self.superview;
while (view)
{
if ([view isKindOfClass:[UITableView class]])
{
self.containingTableView = (UITableView *)view;
break;
}
view = view.superview;
}
}
- (void)dealloc
{
self.containingTableView = nil;
}
#pragma mark -
#pragma mark - Key Value Observing
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == UITableViewPanGestureRecogonizerContext)
{
if ([keyPath isEqual:kUITableViewPanGestureRecognizerStateKeyPath])
{
UIPanGestureRecognizer * panGestureRecognizer = (UIPanGestureRecognizer *)object;
if (panGestureRecognizer.state == UIGestureRecognizerStateBegan)
{
CGPoint velocity = [panGestureRecognizer velocityInView:self.contentCellView];
if (fabs(velocity.y) >= fabs(velocity.x))
{
[self.scrollView setContentOffset:CGPointZero animated:YES];
}
}
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
#pragma mark -
一如既往,非常感谢任何帮助!另外,如果有人需要更多信息,请告诉我。
编辑:
奇怪的是,自定义 UITableViewCell 的 dealloc 方法被调用,并且在抛出异常之前自定义 UITableViewCell 作为观察者被删除。
最佳答案
事实证明,我需要保留对 UITableView 的 UIPanGestureRecognizer 的引用。我很可能最终会子类化 UITableView 以消除一些复杂情况。
关于ios - 崩溃 - UITableViewCell 子类 KVO'ing UITableView.panGestureRecogonizer.state,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28972872/