Как я могу добавить дополнительные дополнительные представления к UICollectionViewFlowLayout с помощью Swift?

Как описано в Руководстве по программированию Представления Коллекции для iOS, если вы хотите добавить новые дополнительные представления или представления художественного оформления к своему Flow Layout, вы должны создать подкласс UICollectionViewFlowLayout.

Мне нужна помощь для реализации следующих шагов в Swift 3:

Стандартный класс макета потока поддерживает только верхний колонтитул раздела и нижний колонтитул раздела, а не виды оформления. Для поддержки дополнительных дополнительных и декоративных видов необходимо как минимум переопределить следующие методы:

В вашем layoutAttributesForElementsInRect: метод вы можете вызвать super, чтобы получить атрибуты макета для ячеек, а затем добавить атрибуты для любых новых дополнительных или декоративных представлений, которые находятся в указанном прямоугольнике. Используйте другие методы для предоставления атрибутов по запросу.

Цели, которых я хотел бы достичь:

  • Один дополнительный вид над каждым элементом
  • Метод делегата как referenceSizeForHeaderInSection определить размер нового дополнительного представления внутри контроллера представления коллекции (return CGSize.zero если не должно быть "заголовка элемента")
  • Точный расчетный размер контента
  • Вставка, обновление и удаление анимации дополнительного вида с каждым элементом

Обновить

Я знаю, что этот вопрос слишком широко определен. Но с помощью Девона и некоторых собственных идей я нашел решение, которое работает для меня.

  1. Подкласс UICollectionViewFlowLayout

    class SBCollectionViewFlowLayout: UICollectionViewFlowLayout { … }

  2. Override layoutAttributesForElements(in rect: CGRect) добавить дополнительный дополнительный вид в каждую ячейку.

    // Check if there already valid layout attributes
    guard var layoutAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
    
    // Try to append new supplementary view to each cell
    // ────────────────────────────────────────────────────────────      
    
    for attributes in layoutAttributes where attributes.representedElementCategory == .cell {
        if let supplementaryAttributes = layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindDateSeparator, at: attributes.indexPath) {
            layoutAttributes.append(supplementaryAttributes)
        }
    }
    
    return layoutAttributes
    
  3. Override layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) рассчитать положение нового дополнительного вида в представлении коллекции.

    switch elementKind {
    
    case UICollectionElementKindDateSeparator:
    
        // Return if there is no collection view or delegate
        guard let delegate = self.collectionView?.delegate as? SBCollectionViewDelegateFlowLayout else { return nil }
    
        // Get the dynamic size of from the delegate
        let size = delegate.collectionView!(self.collectionView!, layout: self, referenceSizeForSeparatorAt: indexPath)
    
        // Return if there the size is (0, 0)
        if size == CGSize.zero { return nil }
    
        // Create new layout attributes for the separator
        // ════════════════════════════════════════════════════════════
    
        let attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, with: indexPath)
    
        if let itemAttributes = layoutAttributesForItem(at: indexPath) {
    
            // Position supplementary view at top left edge of the cell
            // ────────────────────────────────────────────────────────────
    
            attributes.frame = CGRect(x: itemAttributes.frame.origin.x,
                                      y: itemAttributes.frame.origin.y,
                                      width:  size.width,
                                      height: size.height)
    
            // Increase the item’s position on the z axis
            // to be sure that the item appear on top of the cell.
            attributes.zIndex = 1
        }
    
        return attributes
    
    default:
        // If it is not a date separator, return attributes from flow layout
        return super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath)
    }
    
  4. "Расширьте" UICollectionViewDelegateFlowLayout, чтобы спросить делегата о размере нового заголовка.

    public protocol SBCollectionViewDelegateFlowLayout: UICollectionViewDelegateFlowLayout  {
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForSeparatorAt indexPath: IndexPath) -> CGSize
    }
    

TL; DR

Идея состоит в том, чтобы вместо вставки дополнительных дополнительных видов в представление коллекции, а затем для пересчета всех элементов, я добавляю дополнительный вид сверху соответствующей ячейки. Важно добавить динамический верхний отступ в ячейку, чтобы дополнительный вид не перекрывал какой-либо контент внутри ячейки.

Я надеюсь, что это помогает другим с подобной проблемой!

0 ответов

Другие вопросы по тегам