UICollectionViewLayout layoutAttributesForElementsInRect и layoutAttributesForItemAtIndexPath

#ios #objective-c #uicollectionview #uicollectionviewlayout #uicollectionviewdelegate

#iOS #objective-c #uicollectionview #uicollectionviewlayout #uicollectionviewdelegate

Вопрос:

Я реализую пользовательский макет потока. Он имеет 2 основных метода переопределения для определения размещения ячеек: layoutAttributesForElementsInRect и layoutAttributesForItemAtIndexPath .

В моем коде layoutAttributesForElementsInRect вызывается, но layoutAttributesForItemAtIndexPath не является. Что определяет, какой из них вызывается? Где layoutAttributesForItemAtIndexPath вызывается get?

Ответ №1:

layoutAttributesForElementsInRect: не обязательно вызывает layoutAttributesForItemAtIndexPath: .

Фактически, если вы создаете подкласс UICollectionViewFlowLayout , макет потока подготовит макет и кэширует результирующие атрибуты. Итак, при layoutAttributesForElementsInRect: вызове он не будет запрашивать layoutAttributesForItemAtIndexPath: , а просто использует кэшированные значения.

Если вы хотите убедиться, что атрибуты макета всегда изменяются в соответствии с вашим макетом, внедрите модификатор для обоих layoutAttributesForElementsInRect: и layoutAttributesForItemAtIndexPath: :

 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
  NSArray *attributesInRect = [super layoutAttributesForElementsInRect:rect];
  for (UICollectionViewLayoutAttributes *cellAttributes in attributesInRect) {
    [self modifyLayoutAttributes:cellAttributes];
  }
  return attributesInRect;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
  [self modifyLayoutAttributes:attributes];
  return attributes;
}

- (void)modifyLayoutAttributes:(UICollectionViewLayoutAttributes *)attributes
{
  // Adjust the standard properties size, center, transform etc.
  // Or subclass UICollectionViewLayoutAttributes and add additional attributes.
  // Note, that a subclass will require you to override copyWithZone and isEqual.
  // And you'll need to tell your layout to use your subclass in  (Class)layoutAttributesClass
}
  

Комментарии:

1. Что делать, если мне нужен путь к индексу для определения свойства rect атрибута? У меня нет способа передать путь к индексу в функцию modify.

2. A UICollectionViewLayoutAttributes обладает indexPath свойством.

3. @Robert Разве [super layoutAttributesForElementsInRect] не возвращает nil? Такое впечатление у меня сложилось из документов APple.

4. @moonman239 [super layoutAttributesForElementsInRect] возвращает допустимые атрибуты макета при использовании в подклассе UICollectionViewFlowLayout . Он возвращается nil при использовании в пользовательском подклассе UICollectionViewLayout . Если вы пишете свой собственный макет на основе UICollectionViewLayout , вы можете создавать пустые атрибуты макета, используя [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:] .