【问题标题】:Best approach for a UICollectionView to look like the iOS calendar appUICollectionView 看起来像 iOS 日历应用程序的最佳方法
【发布时间】:2015-04-28 18:23:58
【问题描述】:

我正在构建一个应用程序,我确实需要在其中显示一个列表,就像在 iOS 日历应用程序中看到的那样。我需要创建一个collectionView,我可以在其中拥有足够扩展以覆盖其各自时间的单元格,如下所示:

我尝试过各种方法,包括 Github 上的 this project,但我不明白如何在另一个项目中使用

除了这个项目,我在探索不同方法时快速使用 UITableViewController 制作:

但我并没有真正到达我想去的地方。我需要看到第一张图片中的设计,想知道是否有人能指出我实现这一目标的正确方向?

非常感谢您的帮助!

更新:

实际的单元格框不应该代表一个小时的开始,在这个例子中是 10:00? (而不是定制的分隔符)

更新

为什么层次结构是这样的:

这种定位似乎“阻止”了单元格的触摸,并且不会调用 didSelectItemAtIndexPath 方法。这适用于出现在比其他单元格靠后的单元格。

【问题讨论】:

  • 该视图是只显示内容还是用户需要抓取和编辑事件?如果只是显示和选择细节,那应该不会太难
  • @Zil 只是显示并按下事件以转到详细视图控制器
  • 现在我试图写下一个答案,它实际上比预期的要复杂:D
  • github 项目看起来相当不错,如果不是更好的话。究竟是什么让你遇到了麻烦?导入它还是创建集合视图?
  • 我真的完全不明白,我之前没有处理过没有 StoryBoards 的导航,而且我很难分离项目的不同部分并获得概述来理解它.找不到任何教程或方法来使用它:P 我必须将它集成到一个相当大的 StoryBoard 和我的应用程序的逻辑中,所以我需要先了解它

标签: ios objective-c uitableview uicollectionview


【解决方案1】:

您确实应该使用UICollectionView 和自定义布局。只需提供supplementary views 来构建基础每日计划(每小时一次视图),然后使用cells 来安排您的活动。

子类化UICollectionViewLayout时,需要实现几个方法:

  • collectionViewContentSize 应返回等于小时数 (24) 乘以表示一小时的补充视图高度的高度。
  • prepareLayout 几乎可以做所有事情。在该方法中,您计算​​需要使用的每个 layoutAttributes。通过获取事件的时间及其持续时间,您可以计算每个事件的帧。补充视图框架(每个“小时”块)也非常简单,因为它们的高度是固定的(origin.y = 固定高度乘以小时)。
  • layoutAttributesForElementsInRect: 简单地遍历您之前准备的 layoutAttributes 并返回其框架与提供的框架相交的所有框架。
  • layoutAttributesForItemAtIndexPath: 查找并返回与提供的 indexPath 匹配的单元格的 layoutAttributes。

  • layoutAttributesForSupplementaryViewOfKind:atIndexPath 查找并返回补充视图的 layoutAttributes,它对提供的 indexPath 进行数学运算。

接下来,将该布局的实例提供给集合视图:

self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:myCustomLayout]

然后,您只需通过 UICollectionView 的委托和数据源为补充视图(也称为小时块)和单元格提供所需的视图。如果您需要 UIViewController 提供标准委托/数据源所拥有的更多信息,请随意在您的自定义布局中创建自定义委托!

注意:由于指示一小时开始的线在单元格顶部边框下方几个像素处,因此您需要将每次事件移动相同数量的像素。假设您在每行上方有 6 个像素,并且每个小时块的高度为 60 像素,那么如果偶数从凌晨 2 点开始,您将设置其origin.y = 2 * 60 + 6(2 小时 * 60 像素每小时 + 6 像素填充)。您还需要将最后一个单元格块调整为高 6 个像素,因为它下面不会有另一个单元格。

我建议您阅读 the official documentation 关于创建自定义布局的信息。

帮助您:我创建了一个quick sample project,因为制作自己的布局有时会很麻烦。去查看CalendarViewLayout 类,我添加了一些cmets 来解释我是如何处理填充的。这是它的样子:

【讨论】:

  • 非常完整的答案,非常有帮助!
  • 我正在尝试添加一行来显示当前时间,但我不知道如何完成它。我查看了 HourReusableView 类并尝试制作一个类似的类,但无法使其工作。你能帮忙吗?
  • @Erik 我会帮忙,但我现在不能,周日或周一我会有时间。
  • 没问题:) 只要你有时间
  • 你好,你觉得你今天有时间看看这个吗?:)
【解决方案2】:

我不认为这很难做到。

您只需要一个与您尝试过的不同的视角。

使所有 CollectionView 单元格大小相同。它们代表 1 小时的时间,因此它们应该具有相同的大小。

然后在每个单元格中有另一个视图。这是一个表明有一个事件。这个视图你会给一个颜色,并根据事件开始或结束的时间把它放在单元格中。 因此,在 cellForRowAtIndexPath 中,您将检查您的事件,如果此单元格有任何事件,那么您将显示此事件视图,对其着色并定位它。如果将单元格高度设置为 60,则定位视图变得非常容易。例如,如果事件在 1:20 开始,在第 1 小时的单元格处,您将调整事件视图的大小(0、20、320、40)。

【讨论】:

  • 我想这样做,但它有一个小问题。我需要在左边有时间标签,中间有 tableView 分隔符,然后表示例如 07:00 的分隔符不会在 (0,0) 坐标处
  • 不要使用 tableView 分隔符。只需使用高度为 1 的视图并根据需要显示或隐藏或定位它。
  • 是的,这完全没问题。但是,如果我将一个单元格设置为代表一小时,并且我需要在所述分隔符(自定义)旁边有一个标签,那么该标签的一半将在单元格之外,否则自定义分隔符将不代表开始小时。请参阅我的更新以获得一些说明
  • 我不明白这是个问题。是的,你有一个分隔符。是的,它位于单元格下方 10 个像素处。例如,您仍然有相同的距离来表示 12:00 的分隔符和 1:00 的分隔符之间的 1h。
  • 真的。我会看看我能做什么!您是否建议为此使用 CollectionView 或 tableView?
【解决方案3】:

根据 cmets 中关于该问题的讨论,使用问题中链接的 Custom Collection View Layout library 适用于上述问题,可以使用 CocoaPods 轻松集成。

UICollectionView 可以使用自定义UICollectionViewLayout 进行高度自定义。请参阅苹果官方文档creating custom layouts。

坦率地说,Apple 的文档对我们大多数人来说太过分了。因此,您可以查找 (google) custom UICollectionViewLayout tutorial,查看您认为最简单的任何一个,然后继续使用该库来满足您的特定需求。

【讨论】:

    猜你喜欢
    • 2021-03-21
    • 1970-01-01
    • 2012-07-15
    • 2016-06-18
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多