#ios #objective-c #uicollectionview #uicollectionviewcell
#iOS #objective-c #uicollectionview #uicollectionviewcell
Вопрос:
Я хочу установить границу для выбранной ячейки, я сохраняю свойство ячейки, представляющее выбранную ячейку, и манипулирую им:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSArray *eyeArray = [self eyesArrayConfigure][indexPath.row];
if (indexPath.row==5) {
int r = arc4random() % 6;
eyeArray = [self eyesArrayConfigure][r];
}
[borderedCell.contentView.layer setBorderWidth:0.0f] ;
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
borderedCell = cell;
[borderedCell.contentView.layer setBorderColor:self.view.tintColor.CGColor];
[borderedCell.contentView.layer setBorderWidth:3.0f];
}
и cellForView: (Я использую 2 типа идентификаторов ячеек, потому что одна ячейка содержит метку — «Случайная ячейка»:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row ==5) {
UICollectionViewCell *randomCell =[collectionView
dequeueReusableCellWithReuseIdentifier:@"randomCell"
forIndexPath:indexPath];
randomCell.backgroundColor = [UIColor purpleColor];
borderedCell = randomCell;
[borderedCell.contentView.layer setBorderColor:self.view.tintColor.CGColor];
[borderedCell.contentView.layer setBorderWidth:3.0f];
return randomCell;
}
UICollectionViewCell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
NSArray *eyeArray = [self eyesArrayConfigure][indexPath.row];
myCell.backgroundView = [[UIImageView alloc] initWithImage:eyeArray[1]];
return myCell;
}
Что я получаю, так это то, что если щелкнуть одну ячейку, все будет хорошо, пока я не прокручу, а затем я получаю странное поведение, когда пара ячеек может быть с границей.
Спасибо за помощь.
Комментарии:
1. Это то, что мы называем «ошибкой повторного использования ячейки».
2. Итак, каков наилучший способ подойти к этому? с «тегированием» ячеек?
3. Используйте модель представления, сейчас я пишу ответ.
4. Я позволю @CrimsonChris закончить свой ответ (он / она дает хорошие ответы). В двух словах, только метод cellForItemAtIndexPath должен когда-либо изменять состояние ячейки. В вашем случае это должно быть сделано на основе состояния выбора, записанного в другом методе выбора. Но где записать это состояние? В модели, конечно. Это «модель представления», на которую ссылается CrimsonChris.
Ответ №1:
Решение заключается в использовании модели представления. Вы уже делаете это для фоновых представлений ваших ячеек. Примените ту же концепцию для границы.
@interface MyCollectionView ()
@property (nonatomic) NSInteger selectedRow;
@end
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
//update self.selectedRow and either reload entire collection view or just the currently selected and previously selected.
self.selectedRow = indexPath.row;
[collectionView reloadData];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
CGFloat borderWidth = (indexPath.row == self.selectedRow) ? 3.0 : 0.0;
[myCell.contentView.layer setBorderWidth:borderWidth];
return myCell;
}
Комментарии:
1. хорошо, за исключением того, что ваша проверка на равенство слишком сильна. indexPath не будет глубоко равен self.borderedCellIndexPath (selectedIndexPath — лучшее имя). Вместо этого используйте [indexPath compare: self.borderedCellIndexPath] == NSOrderedSame .
2. вы также можете просто перезагрузить по определенному пути индекса. красивее.
3. @danh Оператору потребуется перезагрузить выбранный путь индекса и ранее выбранный путь индекса.
4. О да, хороший момент. Я думаю, что это все же лучший совет для перезагрузки этих двух.
5. Но как насчет вашей логической ошибки? Я бы проголосовал, но это решение только почти правильное. Он не будет работать как закодированный.