ios - 在 Collection View 之上创建 View ?

标签 ios objective-c iphone swift

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

最佳答案

我最终找到了我自己问题的答案。而且,我能够做到这一点,而不必用一堆内部 ScrollView 来破解 collectionView。这就是我所做的。我已经有了我的网格系统,所以我必须在我的 Collection View 中添加一个额外的部分。此部分的项目数取决于我的事件数据源数组:

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

    //calender grid items
    return Constants.numberOfColumns
}

但是,我的 Collection View 的自定义布局需要更新有关 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/

关于ios - 在 Collection View 之上创建 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42545304/

相关文章:

ios - 为什么异步加载图像需要很长时间?

ios - 如何以编程方式将 UITableView 样式从普通样式转换为组样式

ios - UIView动画回原点

iphone - 取消缩放 UIScrollView

iphone - iphone 中的异常处理?

ios - 在 UITableViewCell 的附件 View 中使用自定义按钮的问题

ios - 在您的证书错误上找不到 iPhone 开发者/分发身份

ios - 警报完成未完全正常工作

ios - UICollectionView 在 iOS 11 上覆盖全屏

iphone - UIAlertView 按钮按下导致崩溃,而其他所有按钮都工作正常