I am having difficulty getting my subclass of PFCollectionViewCell
to play nicely with PFImageView
. I am using Storyboards to rig up my PA_ProfileCollectionViewCell.
All I am trying to do is load in an image (which I can get successfully from parse), and assign it to a PFImageView
in my custom cell. I would appreciate any help/insights that could help me from bashing my computer with a baseball bat, and trashing my office in a slow-motion blaze of glory.
My desired outcome: To have a custom cell (subclass of PFCollectionViewCell
) to be used by -collectionView:cellForItemAtIndexPath:object:
The problem: My custom property PFImageView *imageThumb
(on my subclass of PFCollectionViewCell
) does not respond to loadInBackground:
or setFile:
which are two methods on the PFImageView
class.
Here is my code for clarity:
- My custom PFCollectionViewCell: ProfileCollectionViewCell
@interface PA_ProfileCollectionViewCell : PFCollectionViewCell
@property (weak, nonatomic) IBOutlet PFImageView *imageThumb;
@end
- Register the custom class in viewDidLoad
- (void)loadView {
[super loadView];
[self.collectionView registerClass:[PA_ProfileCollectionViewCell class]
forCellWithReuseIdentifier:_cellIdentifier];
}
- Setup the cell in collectionView:cellForItemAtIndexPath:object
This is where the main problem is occurring. My value for cell is successfully being painted darkGray, per the cell.backgroundColor:
call, but all attempts to assign the image to my imageThumb are failing. Notice in the source code below that my imageThumb
doesnt respond to the selectors loadInBackground
or setFile
, which comes stock with 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;
}
The output of all the NSLog()
statements in the code snippet above is:
can cell.imageThumb loadInBackground? : 0 (NO)
can cell.imageThumb setFile? : 0 (NO)
Other things I have tried:
I have picked through the source code on the ParseUIDemo, but all their implementations use the stock PFCollectionViewCell
without any customizations or subclassing, so I tried adapting my project to use their approach, but I could never get things working there either.
I have read through this answer, on SO, which lead me to try crawling through my cell.contentViews.subviews
and cell.subviews
looking for a PFImageView
Neither attempt was successful:
// [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;
}
}
I then tried this answer on SO, and that made me try grabbing the instance of PFImageView
from my storyboard using a tag, which was equally unsuccessful.
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
Lastly, I fed every feasible combination of classNames to all the methods that require classNames in the PFQueryCollectionViewController
. For example: I tried the below lines of code where I swapped out all instances of CLASSNAMEHERE with PA_ProfileCollectionViewCell
, UICollectionViewCell
and PFCollectionViewCell
, all with equal amounts of 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];
Update #01:
Per the suggestion from the user @soulshined I tried skipping the setFile:
call, since it doesn't appear in the API via the Parse docs (but I never got an error, or an unrecognized selector error
when using it), so I tried the below code snippet, with no luck (notice how the setFile:
has been replaced with .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;
}];
}
}];
Update #02
Again, per the suggestion of @soulshined, I used the advice give here, and changed my PFImageView *imageThumb
to a UIImageView *imageThumb
, and tried assigning the NSdata returned from getDataInBackground:withBlock:
to the image instead, here is my code snippet (Note that I do get the "Got Data!" output to the console, but the images are still not showing up):
// pingThumb is a PFFile
[pingThumb getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
NSLog(@"Got data");
UIImage *image = [UIImage imageWithData:data];
[cell.imageThumb setImage:image];
}
}];
So can anyone think of a step that I am missing? Why is it so difficult to get a PFImageView
to load with a subclass of PFCollectionViewCell
?
Thanks in advance for anyone taking the time to help me out!