2016-09-17 10 views
0

Проблема: Я хочу иметь сетку, которая прокручивает вертикально и горизонтально и обновляется через NSFetchedResultsControllerПрокрутка по вертикали и по горизонтали в коллекции View - встроенные макеты потока против пользовательского макета

Решение 1 CoreData в: Вложенные коллекции Представления в потоке Компоновка

  • Первый вид коллекции установки с расположением потока и вертикальной прокрутки
  • Каждая ячейка этого Колле ction view is сам вид сбоку в раскладке, который прокручивается горизонтально.
  • Затем я должен прикрепить NSFetchedResultsController к каждому из этих представлений детской коллекции.

Решение 2: Реализация пользовательского потока макета

  • Положите один вид коллекции в пользовательском макете.
  • С одной NSFetchedResultsController

Теперь, 2, казалось бы, гораздо проще - но создать макет вид пользовательского коллекции не то, что я делал раньше, и Apple, документы состояние:

*»* Прежде чем приступать к созданию пользовательских макетов, подумайте над тем, действительно ли это необходимо. Класс UICollectionViewFlowLayout обеспечивает значительный объем поведения, который уже оптимизирован для эффективности .... »

Итак, мой вопрос: is Это ситуация, при которой пользовательский макет потока действительно облегчит жизнь? Если да, есть ли у кого-нибудь примеры Swift? Я видел несколько в Obj-C, но ни один в Swift ...

+0

Ач - подклассификация UICollectionViewFlowLayout должна быть разумной средой? – thesundayscientist

ответ

1

Вот мой пользовательский CollectionViewLayout в Swift 2.3. Для его использования вы должны реализовать TwoWayCollectionViewLayoutDatasource.

Надеюсь, это может вам помочь.

protocol TwoWayCollectionViewLayoutDatasource: NSObjectProtocol { 
    func twoWayCollectionViewLayout(layout: TwoWayCollectionViewLayout, colectionView: UICollectionView, widthForColumnIndex index: Int) -> CGFloat 
    func twoWayCollectionViewLayout(layout: TwoWayCollectionViewLayout, colectionView: UICollectionView, heighForRowIndex index: Int) -> CGFloat 
    func twoWayCollectionViewLayoutNumberOfFixColumns(layout: TwoWayCollectionViewLayout, colectionView: UICollectionView) -> Int 
    func twoWayCollectionViewLayoutNumberOfFixRows(layout: TwoWayCollectionViewLayout, colectionView: UICollectionView) -> Int 
} 

class TwoWayCollectionViewLayout: UICollectionViewLayout { 
    private var itemAttributes : [[UICollectionViewLayoutAttributes]] = [] 
    private var itemsSize : [[CGSize]] = [] 
    private var contentSize : CGSize = CGSizeZero 

    weak var dataSource: TwoWayCollectionViewLayoutDatasource! 

    override func invalidateLayout() { 
     super.invalidateLayout() 
    } 

    override func prepareLayout() { 
     if self.collectionView?.numberOfSections() == 0 { 
      return 
     } 

     let numberOfColumns = self.collectionView!.numberOfItemsInSection(0) 
     let numberOfRows = self.collectionView!.numberOfSections() 
     let numberOfFixColumns = self.dataSource.twoWayCollectionViewLayoutNumberOfFixColumns(self, colectionView: self.collectionView!) 
     let numberOfFixRows = self.dataSource.twoWayCollectionViewLayoutNumberOfFixRows(self, colectionView: self.collectionView!) 

     if self.itemAttributes.count > 0 { 
      for var rowIndex = 0; rowIndex < numberOfRows; rowIndex++ { 
       for var columnIndex = 0; columnIndex < numberOfColumns; columnIndex++ { 
        if rowIndex < numberOfFixRows || columnIndex < numberOfFixColumns { 
         if let attributes = self.layoutAttributesForItemAtIndexPath(NSIndexPath(forItem: columnIndex, inSection: rowIndex)) { 
          var frame = attributes.frame 
          if rowIndex < numberOfFixRows { 
           var yPosition = self.collectionView!.contentOffset.y 
           for var i = 0; i < rowIndex; i++ { 
            yPosition += self.itemsSize[i][columnIndex].height 
           } 
           frame.origin.y = yPosition 
          } 
          if columnIndex < numberOfFixColumns { 
           var xPosition = self.collectionView!.contentOffset.x 
           for var i = 0; i < columnIndex; i++ { 
            xPosition += self.itemsSize[rowIndex][i].width 
           } 
           frame.origin.x = xPosition 
          } 

          attributes.frame = frame 
         } 
        } 
       } 
      } 
     } else { 
      if (self.itemsSize.count == 0) { 
       self.calculateItemsSize() 
      } 

      var xOffset : CGFloat = 0 
      var yOffset : CGFloat = 0 
      var contentWidth : CGFloat = 0 
      var contentHeight : CGFloat = 0 

      for var rowIndex = 0; rowIndex < numberOfRows; rowIndex++ { 
       var rowAttributes: [UICollectionViewLayoutAttributes] = [] 
       for var columnIndex = 0; columnIndex < numberOfColumns; columnIndex++ { 
        let itemSize = self.itemsSize[rowIndex][columnIndex] 
        let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: NSIndexPath(forItem: columnIndex, inSection: rowIndex)) 
        attributes.frame = CGRectIntegral(CGRectMake(xOffset, yOffset, itemSize.width, itemSize.height)) 

        if columnIndex < numberOfFixColumns && rowIndex < numberOfFixRows { 
         attributes.zIndex = 1024; 
        } else if columnIndex < numberOfFixColumns || rowIndex < numberOfFixRows { 
         attributes.zIndex = 1023 
        } else { 
         attributes.zIndex = 1000 
        } 

        if columnIndex == 0 { 
         var frame = attributes.frame 
         frame.origin.x = self.collectionView!.contentOffset.x 
         attributes.frame = frame 
        } 

        if rowIndex == 0 { 
         var frame = attributes.frame 
         frame.origin.y = self.collectionView!.contentOffset.y 
         attributes.frame = frame 
        } 

        rowAttributes.append(attributes) 

        xOffset += itemSize.width 

        if columnIndex == numberOfColumns - 1 { 
         if xOffset > contentWidth { 
          contentWidth = xOffset 
         } 
         xOffset = 0 
         yOffset += itemSize.height 
        } 
       } 

       self.itemAttributes.append(rowAttributes) 
      } 

      if let attributes = self.itemAttributes.last?.last as UICollectionViewLayoutAttributes? { 
       contentHeight = attributes.frame.origin.y + attributes.frame.size.height 
       self.contentSize = CGSizeMake(contentWidth, contentHeight) 
      } 
     } 
    } 

    override func collectionViewContentSize() -> CGSize { 
     return self.contentSize 
    } 

    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? { 
     if self.itemAttributes.count > indexPath.section { 
      if self.itemAttributes[indexPath.section].count > indexPath.item { 
       return self.itemAttributes[indexPath.section][indexPath.item] 
      } else { 
       print("Dont match row \(indexPath)") 
      } 
     } else { 
      print("Dont match section \(indexPath)") 
     } 
     return nil 
    } 

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 
     var attributes = [UICollectionViewLayoutAttributes]() 
     for section in self.itemAttributes { 
      let filteredArray = section.filter({ (item) -> Bool in 
       return CGRectIntersectsRect(rect, item.frame) 
      }) 

      attributes.appendContentsOf(filteredArray) 
     } 
     return attributes 
    } 

    override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { 
     return true 
    } 

    func calculateItemsSize() { 
     let numberOfColumns = self.collectionView!.numberOfItemsInSection(0) 
     let numberOfRows = self.collectionView!.numberOfSections() 

     self.itemsSize.removeAll() 
     for var rowIndex = 0; rowIndex < numberOfRows; rowIndex++ { 
      var rowSize: [CGSize] = [] 
      for var columnIndex = 0; columnIndex < numberOfColumns; columnIndex++ { 
       let w = self.dataSource.twoWayCollectionViewLayout(self, colectionView: self.collectionView!, widthForColumnIndex: columnIndex) 
       let h = self.dataSource.twoWayCollectionViewLayout(self, colectionView: self.collectionView!, heighForRowIndex: rowIndex) 
       rowSize.append(CGSizeMake(w, h)) 
      } 

      self.itemsSize.append(rowSize) 
     } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^