willTransitionToState(UITableViewCell)在某些情况下不会被调用

时间:2013-11-21 11:10:54

标签: ios cocoa-touch uitableview uitextfield

我想要实现的目标

我有一个自定义UITableViewCell,其内容为UITextField,用于就地编辑。在cell's处于编辑模式时应启用UITableView字段,但在显示单元格的删除确认时 NOT

我是如何实现的

我已将UITableViewCell子类化,并因此覆盖了willTransitionToState方法:

- (void)willTransitionToState:(UITableViewCellStateMask)state {
   [super willTransitionToState:state];
   self.nameField.enabled = !(state & UITableViewCellStateShowingDeleteConfirmationMask)
                            && (state & UITableViewCellStateEditingMask);
}

问题

我90%的路在那里。

在用户按下单元格的“ - ”按钮后,将调用

'willTransitionToState'。显示删除确认,并根据需要禁用我的文本字段。但是,如果用户决定不删除单元格并通过向右滑动隐藏删除确认,该怎么办? 在这种情况下,不会调用“willTransitionToState”。

因此,我的文本字段仍处于禁用状态,即使隐藏删除确认时应启用它。你会认为,鉴于存在'UITableViewCellStateShowingDeleteConfirmationMask'标志这一事实,'willTransitionToState'将被对称调用,但情况似乎并非如此。

更新

似乎UITableViewCell的'showingDeleteConfirmation'属性总是给出正确的结果。因此理论上我可以遍历调用“showingDeleteConfirmation”的每个单元格并相应地启用或禁用每个文本字段。这是低效率和kludgy。我正在考虑提交关于“willTransitionToState”的错误报告,但我需要更多的数据点。还有其他人遇到过这个问题吗?

2014年4月29日

Apple确认这是一个错误。截至今天,错误报告仍然是开放的。

1 个答案:

答案 0 :(得分:0)

为KVO声明一个上下文:

static int KVOContext;

使用自定义getter获取单元格中的scrollView

- (UIScrollView *)scrollViewToObserve
{
    UIView *view = self.subviews[0];
    return (view != nil && [view isKindOfClass:[UIScrollView class]]) ? (UIScrollView *)view : nil;
}

将观察者添加到scrollView' contentOffset

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self.scrollViewToObserve addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:&KVOContext];
    }
    return self;
}

删除dealloc中的观察者:

- (void)dealloc
{
    [self.scrollViewToObserve removeObserver:self forKeyPath:@"contentOffset" context:&KVOContext];
}

使用KVO观察对contentOffset的更改,但对showingDeleteConfirmation州使用enabled

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (context == &KVOContext) {
        if ([keyPath isEqualToString:@"contentOffset"]) {
            self.textField.enabled = !self.showingDeleteConfirmation;
        }
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

警告:视图层次结构可能会在以后的更新中更改