在集合视图顶部创建视图?

时间:2017-03-02 01:34:09

标签: ios objective-c iphone swift

目前,我有一个日历网格系统。我正在尝试实现一个功能,我可以在日历中显示事件块。因此,我希望能够实现this,用户可以通过点击单元格在网格系统中的任何位置添加“无标题”块。我的第一个想法是在UICollectionView之外添加一个视图,但是当我滚动日历时。 “Untitled”块仍然存在,并且仍然在屏幕上。我需要在集合布局中添加一个单元格,以使其保持在集合视图的流程中。要构建网格系统,我必须创建一个UICollectionViewLayout的自定义子类,所以我没有使用UICollectionViewFlowLayout。我仍然有点迷失如何在另一个单元格上方添加单元格,有关实现此功能的最佳方法的任何想法?

1 个答案:

答案 0 :(得分:3)

我最终找到了自己问题的答案。而且,我能够做到这一点,而无需使用一堆内部滚动视图来破解collectionView。这就是我的所作所为。我已经有了我的网格系统,所以我不得不在我的集合视图中添加一个额外的部分。此部分的项目数取决于我的事件数据源数组:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if section == Constants.numberOfSections {
        //custom event section
        return events.count
    }

    //calender grid items
    return Constants.numberOfColumns
}

但是,我需要更新有关cellAttributes的集合视图的自定义布局。如果我没有告诉它添加了一个新的单元格,那么它会崩溃,因为它无法找到相应的网格成员或将单元格添加到网格中,就像它是网格的另一部分一样。因此,我必须更新自定义布局类中的cellAttributes,然后手动计算单元格在布局中的放置位置。因此,基本上每次添加事件单元格时,布局都必须手动计算该单元格在网格中的位置。这是我在自定义布局子类中手动计算事件坐标的函数(相关部分在自定义事件注释中):

fileprivate func setCellAttributes(item: Int, section: Int) {
    // Build the UICollectionVieLayoutAttributes for the cell.
    let cellIndex = IndexPath(item: item, section: section)
    var cellWidth: Double = CELL_WIDTH
    var cellHeight: Double = CELL_HEIGHT
    var xPos: Double = 0
    var yPos = Double(section) * CELL_HEIGHT

    if section == collectionView!.numberOfSections - 1 {
        //custom event items
        let rect = getCustomEventRect(item: item)
        xPos = Double(rect.x)
        yPos = Double(rect.y)
        cellHeight = Double(rect.height)
        cellWidth = Double(rect.width)
    } else if item == 0 {
        //the y axis cells
        cellWidth = yAxisCellWidth
    } else {
        //all other cells
        xPos = calculateXPos(item: item)
    }

    let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex)
    cellAttributes.frame = CGRect(x: xPos, y: yPos, width: cellWidth, height: cellHeight)

    // Determine zIndex based on cell type.
    if section == 0 && item == 0 {
        //top left corner cell
        cellAttributes.zIndex = 5
    } else if section == 0 {
        //y axis cells
        cellAttributes.zIndex = 4
    } else if section == collectionView!.numberOfSections - 1 {
        //custom event cells
        cellAttributes.zIndex = 2
    } else if item == 0 {
        //top x axis cells
        cellAttributes.zIndex = 3
    }  else {
        //all background schedule cells
        cellAttributes.zIndex = 1
    }

    // Save the attributes.
    cellAttrsDictionary[cellIndex] = cellAttributes
}

此外,每次我更新viewController中的事件时,我都必须更新布局中的事件。所以,我在viewController中实现了这个:

var events: [CustomEvent] = [] {
    didSet {
        if let layout = theCollectionView.collectionViewLayout as? ScheduleCollectionViewLayout {
            layout.events = events
        }
    }
}

并且,当用户点击添加新事件时,我确保相应地更新布局:

func removeEventCell(at indexPath: IndexPath) {
    let eventSection: Int = collectionView!.numberOfSections - 1
    let totalEventItems: Int = collectionView!.numberOfItems(inSection: eventSection)

    //decrementing all indexPaths above the deleted event cell, so the attribute dictionary will be up to date, when reloadSections is run by the collectionView.
    for item in 0..<totalEventItems where item > indexPath.item {
        let targetIndexPath = IndexPath(item: item - 1, section: eventSection)
        let cellAttr = cellAttrsDictionary[IndexPath(item: item, section: eventSection)]
        cellAttr?.indexPath = targetIndexPath
        cellAttrsDictionary[targetIndexPath] = cellAttr

    }

    let lastIndexPath = IndexPath(item: totalEventItems - 1, section: eventSection)
    cellAttrsDictionary.removeValue(forKey: lastIndexPath)
}

fileprivate func addEventCellAttributes(numOfEventsToAdd: Int) {
    for num in 1...numOfEventsToAdd {
        setCellAttributes(item: events.count - num, section: collectionView!.numberOfSections - 1)
    }
}

这是计算放置单元格的位置的非常手动的过程,但它使collectionView保持平稳运行并允许将单元格放在单元格之上。我的答案总结是我为自定义事件添加了一个新的部分,我不得不手动计算这些单元格的位置应该是什么,而不是让它们与网格系统一起流动。我的互动日历现在完美无缺。如果您在尝试创建网格系统时遇到问题,我使用了本教程: https://www.credera.com/blog/mobile-applications-and-web/building-a-multi-directional-uicollectionview-in-swift/