ReactiveCocoa 连接到 UICollectionViewCell 子视图

ReactiveCocoa connection to UICollectionViewCell subview

我有一个 UICollectionView,它加载我的自定义 UICollectionViewCell,其中有一个 UITextField 和一个 UILabel

在我的 cellForItemAtIndexPath 中,我正在做这样的事情:

        -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {

        BBCollectionViewTextFieldCell *textFieldCell = [collectionView dequeueReusableCellWithReuseIdentifier:[BBCollectionViewTextFieldCell reuseIdentifier] forIndexPath:indexPath];
        NSString *label = @"";

                switch (indexPath.item){
                    case 0:
                        label = @"Label One";
                        self.firstTextField = textFieldCell.textField;
                        textFieldCell.textField.text = self.viewModel.labelOneData;
                        break;
                    case 1:
                        label = @"Label Two";
                        self.secondTextField = textFieldCell.textField;
                        textFieldCell.textField.text = self.viewModel.labelTwoData;
                        break;
                    case 2:
                        label = @"Label Three";
                        self.thirdTextField = textFieldCell.textField;
                        textFieldCell.textField.text = self.viewModel.labelThreeData;
                        break;
                     }

                   textFieldCell.label.text = label;
                    textFieldCell.textField.delegate = self;
    return textFieldCell; 
    }

然后我使用正常的 UITextFieldDelegate 方法来处理文本输入,就像这样:

-(void)textFieldDidEndEditing:(UITextField *)textField{

if (textField == self.firstTextField){
   //Do something with it
}
//And so on for the rest... 
}

到目前为止一切顺利...

这是什么问题?

问题是如果我重新加载 UICollectionView 会发生以下情况:

或其任意组合。 UILabel 都是正确的 - 但是实际的 UItextField 似乎已经混淆了。第一个 UICollectionViewCellUitextField 实际上会有来自另一个单元格的文本字段的数据。

起初我认为这是一个重用问题 - 然而,因为我的单元格永远不会滚动到屏幕外并且数据非常静态,(总是有 X 数量的单元格,不多也不少) - 所以它可以'这不是重用问题。

我修改了代码,因此我的 UIViewController 中没有 UitextField Properties 代码所在的位置 - 并依赖 indexPath 获取文本字段。像这样 cellForItemAtIndexPath

switch (indexPath.item){
                case 0:
                    label = @"Label One";
                    textFieldCell.textField.text = self.viewModel.labeloneData;
                    break;

和:

    -(void)textFieldDidEndEditing:(UITextField *)textField{

NSIndexPath *indexPath = [self.collectionView indexPathForCellContaininView:textField];

    if(indexPath.item == 0){
       //Do something with it
    }
    //And so on for the rest... 
    }

这解决了问题,但这不是我想要做的。我的 UIViewController

中需要 UItextField 属性

我在实现中声明了 UitextField Properties

@property (strong, nonatomic)  UITextField *firsttextField;

我也发布了一个非常相似的问题,但使用 UITableView 代替,并得出结论它与单元格重用有关 - 但我不相信它了(同样,该问题代码中的设置几乎相同对于这个问题 - 虽然是同样的问题)

我觉得问题出在哪里

我认为这与 UITableViewUiCollectionView 重用细胞的方式无关。我认为问题出在 viewController's 代码和我的 UItextField 属性的实例中。不过我可能在这里偏离了基础。

我知道我列出了一个可能的解决方法 - 但是我想深入了解这个问题并找出它发生的原因。

保持指向 UITableView/UICollectionView 单元格子视图的指针很麻烦,因为单元格在滚动时被重复使用——并且可能在重新加载时被打乱。重用后,您认为在一个索引路径中的子视图现在在另一个索引路径中。

最常见的解决方案是自定义单元格中的插座。其他人会在每次配置单元时更新标签。其他人喜欢快速搜索视图层次结构(例如,点击按钮)以找出子视图对应的索引路径。

但是由于 ReactiveCocoa 完全是关于模型-视图连接的,所以它需要一对指针。幸运的是,它还提供了与单元重用相对应的结束条件。 This gist demonstrates 如何为 table 视图单元格的子视图建立反应式连接。复制到这里...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    UITableViewCell *cell =
        [tableView dequeueReusableCellWithIdentifier:REUSABLE_CELL_ID];
    UILabel *label = (UILabel *)[cell viewWithTag:VIEW_TAG];
    Model *someModel = [self getModelFromIndexPath:indexPath];
    //  `takeUntil:` makes the RACObserve() signal complete (and thus breaks the subscription)
    //  when the cell is recycled.
    RAC(label, text) = [RACObserve(someModel, someKey)
        takeUntil:cell.rac_prepareForReuseSignal];
    return cell;
}