PF ImageView 不适用于 PF CollectionViewCell 的子类

PFImageView not working on sublass of PFCollectionViewCell

我很难让 PFCollectionViewCell 的子 class 与 PFImageView 一起玩。 我正在使用故事板来组装我的 PA_ProfileCollectionViewCell。

我想要做的就是加载图像(我可以从解析中成功获得),并将其分配给自定义单元格中的 PFImageView。我将不胜感激任何 help/insights 可以帮助我免于用棒球棒猛击我的计算机,并以慢动作的荣耀之火毁掉我的办公室。

我想要的结果: 有一个自定义单元格(PFCollectionViewCell 的子 class)供 -collectionView:cellForItemAtIndexPath:object:[=60 使用=]

问题:我的自定义属性PFImageView *imageThumb(在我的PFCollectionViewCell子class上)没有响应loadInBackground:setFile: 这是 PFImageView class.

上的两种方法

为了清楚起见,这是我的代码:

- 我的自定义 PFCollectionViewCell:ProfileCollectionViewCell

@interface PA_ProfileCollectionViewCell : PFCollectionViewCell
@property (weak, nonatomic) IBOutlet PFImageView *imageThumb;
@end

- 在viewDidLoad

中注册自定义class
- (void)loadView {
    [super loadView];
    [self.collectionView registerClass:[PA_ProfileCollectionViewCell class]
            forCellWithReuseIdentifier:_cellIdentifier];
}

- 在collectionView:cellForItemAtIndexPath:object
中设置单元格 这是发生主要问题的地方。根据 cell.backgroundColor: 调用,我的单元格值已成功绘制为深灰色,但将图像分配给我的 imageThumb 的所有尝试都失败了。请注意,在下面的源代码中,我的 imageThumb 不响应选择器 loadInBackgroundsetFile,后者随 PFImageView.

一起提供
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath
                                  object:(PFObject *)object {


    PA_ProfileCollectionViewCell *cell = (PA_ProfileCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:_cellIdentifier
                                                                                                                   forIndexPath:indexPath];
    cell.backgroundColor = [UIColor grayColor];

    // Load the photo
    PFFile *pingThumb = [object objectForKey:@"imageMediumFile"];
    if (pingThumb){

        BOOL canLoadInBackground = [cell.imageThumb respondsToSelector:@selector(loadInBackground:)];
        BOOL canSetFile = [cell.imageThumb respondsToSelector:@selector(setFile:)];

        NSLog(@"can cell.imageThumb loadInBackground? : %hhd", canLoadInBackground);
        NSLog(@"can cell.imageThumb setFile? : %hhd", canSetFile);

        [cell.imageThumb setFile:pingThumb];
        [cell.imageThumb loadInBackground:^(UIImage *image, NSError *error) {
            if(!error){
                NSLog(@"CODE WON'T REACH THIS POINT.");
                NSLog(@"loadInBackground doesn't exist on cell.imageThumb)");
                [UIView animateWithDuration:0.2f animations:^{
                    cell.imageThumb.alpha = 1.0f;
                }];
            }
        }];

    }

    return cell;
}

上面代码片段中所有NSLog()语句的输出为:

can cell.imageThumb loadInBackground? : 0 (NO)
can cell.imageThumb setFile? : 0 (NO)

我尝试过的其他事情:

我已经在 ParseUIDemo 上挑选了源代码,但是他们所有的实现都使用了股票 PFCollectionViewCell,没有任何自定义或子classing,所以我尝试调整我的项目使用他们的方法,但我也永远无法在那里工作。

我在 SO 上通读了 this answer,这导致我尝试爬行我的 cell.contentViews.subviewscell.subviews 寻找 PFImageView 两次尝试都没有成功:

// [DIDN'T WORK]
for (UIView *subview in cell.contentView.subviews) {
    if ([subview isKindOfClass:[PFImageView class]]) {
        NSLog(@"Yay! I found a PFImageView"); // Never gets called
        break;
    }
}

然后我在 SO 上尝试 this answer,这让我尝试使用标签从故事板中获取 PFImageView 的实例,但同样不成功。

PFImageView *photoView = (PFImageView *)[cell.contentView viewWithTag:242];
if(!photoView) NSLog(@"Can't find PFImageView with tag in Storyboards");
// -> Can't find PFImageView with tag in Storyboards

最后,我将 classNames 的每个可行组合提供给 PFQueryCollectionViewController 中需要 classNames 的所有方法。例如:我尝试了下面的代码行,其中我用 PA_ProfileCollectionViewCellUICollectionViewCellPFCollectionViewCell 交换了 CLASSNAMEHERE 的所有实例,所有实例都具有相同数量的 FAIL:

// the cell (with casting)
CLASSNAMEHERE *cell = (CLASSNAMEHERE *)[cv dequeueReusableCellWithReuseIdentifier:...];

// the cell (without casting)
CLASSNAMEHERE *cell = [cv dequeueReusableCellWithReuseIdentifier:...];

// registering the class
[self.collectionView registerClass:[CLASSNAMEHERE class]
        forCellWithReuseIdentifier:_cellIdentifier];

更新#01:

根据用户@soulshined 的建议,我尝试跳过 setFile: 调用,因为它没有出现在 API via the Parse docs 中(但我从未收到错误,或 unrecognized selector error 使用它时),所以我尝试了下面的代码片段,但没有成功(注意 setFile: 是如何被 .file:

替换的
cell.imageThumb.file = pingThumb;
//[cell.imageThumb setFile:pingThumb];
[cell.imageThumb loadInBackground:^(UIImage *image, NSError *error) {

    if(!error){
        NSLog(@"CODE WON'T REACH THIS POINT.");
        NSLog(@"loadInBackground doesn't exist on cell.imageThumb)");
        [UIView animateWithDuration:0.2f animations:^{
            cell.imageThumb.alpha = 1.0f;
        }];
    }
}];

更新#02

再次,根据@soulshined 的建议,我 used the advice give here,并将我的 PFImageView *imageThumb 更改为 UIImageView *imageThumb,并尝试将从 getDataInBackground:withBlock: 返回的 NSdata 分配给取而代之的是图像,这是我的代码片段(请注意,我确实将 "Got Data!" 输出到控制台,但图像仍未显示):

// pingThumb is a PFFile
[pingThumb getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
        if (!error) {
            NSLog(@"Got data");
            UIImage *image = [UIImage imageWithData:data];
            [cell.imageThumb setImage:image];
        }
    }];

所以有人能想到我遗漏的步骤吗?为什么用 PFCollectionViewCell 的子 class 加载 PFImageView 这么难?

在此先感谢任何花时间帮助我的人!

PA_ProfileCollectionViewCell 有 NIB 文件吗?如果是,您需要注册 NIB 文件而不是 Class。尝试这样的事情:

// LOAD UP THE NIB FILE FOR THE CELL
UINib *nib = [UINib nibWithNibName:@"PA_ProfileCollectionViewCell" bundle:nil];

// REGISTER THE NIB FOR THE CELL WITH THE TABLE
[self.collectionView registerNib:nib forCellWithReuseIdentifier:@"CustomNibCellId"];

您面临的问题是您在 -viewDidLoad 方法中注册了 class,但您是通过 Storyboard 中的 Prototype 单元设置单元。

如果您参考 "Cell and View Reuse" section here,您将阅读(强调我的):

... if the cell or supplementary views are created using prototypes within a storyboard it is not necessary to register the class in code and, in fact, doing so will prevent the cell or view from appearing when the application runs.

这就是您的 PFImageViews 没有运行的原因,因为您在调用 -registerClass:forCellWithReuseIdentifier: 后破坏了您在 Storyboards 中建立的原型连接,并且您的 PFImageViews 在运行时丢失了。

因此,要解决您的问题,只需从您的视图控制器中删除 -registerClass:forCellWithReuseIdentifier

等等,问题解决了...

因此下面的代码 在您的视图控制器中的任何地方都不需要,因为同样,如果您使用的是原型单元格,则无需注册 class :

// Not needed when using Prototype cells in Storyboards!
[self.collectionView registerClass:[PA_ProfileCollectionViewCell class]
            forCellWithReuseIdentifier:_cellIdentifier];

删除 registerClass 代码后,您在上面问题的代码示例中使用 PFImageView 的代码应该可以正常工作。

希望对您有所帮助!


附带说明一下,在 -collectionView:cellForItemAtIndexPath:object

中实例化自定义单元时无需强制转换
// this is all you need
SomeCustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:_cellId]; 

// the casting example below is redundant and unnecessary, stick with the top example 
SomeCustomCell *cell = (SomeCustomCell *)[collectionView dequeueReusableCellWithReuseIdentifier:_cellId];