PFImageView не работает на подклассе PFCollectionViewCell
У меня проблемы с получением моего подкласса PFCollectionViewCell
хорошо играть с PFImageView
, Я использую раскадровки для установки моего PA_ProfileCollectionViewCell.
Все, что я пытаюсь сделать, это загрузить изображение (которое я могу успешно получить из анализа), и назначить его PFImageView
в моей таможенной камере. Я был бы признателен за любую помощь / понимание, которое могло бы помочь мне избить мой компьютер бейсбольной битой и разгромить мой офис медленной вспышкой славы.
Мой желаемый результат: иметь собственную ячейку (подкласс PFCollectionViewCell
) для использования -collectionView:cellForItemAtIndexPath:object:
Проблема: мое пользовательское свойство PFImageView *imageThumb
(на моем подклассе PFCollectionViewCell
) не отвечает на loadInBackground:
или же setFile:
которые являются двумя методами на PFImageView
учебный класс.
Вот мой код для ясности:
- Мой пользовательский PFCollectionViewCell: ProfileCollectionViewCell
@interface PA_ProfileCollectionViewCell : PFCollectionViewCell
@property (weak, nonatomic) IBOutlet PFImageView *imageThumb;
@end
- Зарегистрируйте пользовательский класс в viewDidLoad
- (void)loadView {
[super loadView];
[self.collectionView registerClass:[PA_ProfileCollectionViewCell class]
forCellWithReuseIdentifier:_cellIdentifier];
}
- Настройте ячейку в collectionView:cellForItemAtIndexPath:object
Вот где возникает основная проблема. Мое значение для ячейки успешно окрашивается в DarkGray, в соответствии с cell.backgroundColor:
вызов, но все попытки присвоить изображение моему imageThumb терпят неудачу. Обратите внимание в исходном коде ниже, что мой imageThumb
не отвечает на селекторы loadInBackground
или же setFile
, который поставляется с 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
без каких-либо настроек или подклассов, поэтому я попытался адаптировать свой проект, чтобы использовать их подход, но я так и не смог добиться успеха.
Я прочитал этот ответ на SO, что заставило меня попробовать пролистать мой cell.contentViews.subviews
а также cell.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, и это заставило меня попробовать захватить экземпляр 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 всем методам, которые требуют classNames в PFQueryCollectionViewController
, Например: я попробовал приведенные ниже строки кода, где я поменял местами все экземпляры CLASSNAMEHERE PA_ProfileCollectionViewCell
, UICollectionViewCell
а также PFCollectionViewCell
, все с равным количеством 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 через документы Parse (но я никогда не получал ошибку или 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, я воспользовался советом, приведенным здесь, и изменил свой PFImageView *imageThumb
к UIImageView *imageThumb
и попытался присвоить NSdata, возвращенный из getDataInBackground:withBlock:
вместо этого вот мой фрагмент кода (обратите внимание, что я получаю вывод "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];
}
}];
Так может кто-нибудь придумать шаг, который мне не хватает? Почему так сложно получить PFImageView
загрузить с подклассом PFCollectionViewCell
?
Заранее спасибо всем, кто нашел время, чтобы помочь мне!
2 ответа
Проблема, с которой вы сталкиваетесь, заключается в том, что вы регистрируете класс в своем -viewDidLoad
метод, но вы настраиваете свою ячейку через ячейку Prototype в раскадровке.
Если вы обратитесь к разделу "Повторное использование ячеек и представлений" здесь, вы прочтете (выделение мое):
... если ячейка или дополнительные представления создаются с использованием прототипов в раскадровке, нет необходимости регистрировать класс в коде, и, фактически, это предотвратит появление ячейки или представления при запуске приложения.
Вот почему ваш PFImageViews
не вела себя, потому что вы разрывали соединения Prototype, которые вы установили в раскадровке после -registerClass:forCellWithReuseIdentifier:
был вызван, и ваши PFImageViews были потеряны в режиме ожидания.
Итак, чтобы решить вашу проблему, просто УДАЛИТЕ -registerClass:forCellWithReuseIdentifier
с вашей точки зрения контроллера.
Эт вуаля, проблема решена...
Так что этот код ниже не нужен нигде в вашем контроллере представления, потому что, опять же, если вы используете ячейки прототипа, нет необходимости регистрировать класс:
// 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];
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"];