类似Springboard文件夹的UICollectionView

35

我正在尝试实现以下效果:

UICollectionView 显示一个对象类型的网格单元,例如相册。当我点击其中一个项目时,我想要将该元素滚动到屏幕顶部并从其打开类似 Springboard 的文件夹。在文件夹区域内,应显示另一个集合,其中包含详细项,即该相册的单个照片。在“父”视图中点击可以关闭文件夹。请参见此架构:

进入图像描述

到目前为止,我已经为相册创建了常规集合视图。选择一个后,它会将所选项目滚动到顶部,然后使用JWFolders 在该位置打开一个空文件夹。一旦显示出来,我触发周围的UINavigationController来推送我的第二个视图控制器,其中包含详细项。这个视图被布置好,以便让用户感觉它仍然是同一个视图。

这种方法存在几个问题,我想知道如何更好地解决它们:

  1. JWFolders 打开效果需要截屏并将其两个部分向上/向下动画。这是可以的,但在 iPad3 上非常慢,因为它移动了很多像素并且 iPad3 的 GPU 不太符合要求。

  2. 第二个视图需要完全匹配在第一个视图之上。这可能会意外破坏。

  3. 我的转换视图控制器的动画选择受限。默认的来自右侧的UINavigationController 推送不太适合。我将其覆盖以进行交叉溶解,但仍然远非理想。

我希望能够获得有关如何以可维护的方式解决此问题的指针,而不需要过多地对框架进行创意性的破解。我可能会忽略一些显而易见的东西,因此赞赏提供示例或一般建议的指针。
更新:
我稍微改变了方法。现在我使用一个容器视图控制器,其中包含两个嵌入的集合视图控制器。一个用于“相册”,另一个用于底部的“照片”部分。在两个之间使用UIImageView可以完成指向上的三角形。从维护的角度来看,这也很好,因为处理两个集合的维护完全是分开的。
应用程序使用自动布局,因此我可以通过修改约束来更改每个嵌入视图所占的空间。这比使用JWFolders基于屏幕截图的方法要快得多,并且在iPad3上也可以很好地工作。
这几乎让我达到了目标。仅剩的问题是如何正确打开动画。我想同时滚动相册集合,使点击的项目移到顶部,并展开带有指向Album单元格的照片集合。
我是否可以通过布局约束“连接”低视图和该单元格,以便scrollToItemAtIndexPath:atScrollPosition:animated:调用打开低视图?

你使用了什么代码来实现对imageView集合的动画打开? - AMayes
暂时没有它,但基本上是将我的视图下边缘与父视图底部之间的自动布局约束动画化,从其原始值到0。 - Daniel Schneller
如果您熟悉 Xcode Instruments,可以尝试对代码进行时间分析。可能存在可以改进 JWFolders 动画方式的地方,因为它正在执行的动画不应该消耗那么多资源。 - Andrew Theis
问题在于,在Retina iPad 3上,当您拍摄分屏截图并移动每个半屏时,需要移动大量像素。这只是硬件的限制(以及我不愿意为此开始深入研究OpenGL)。 - Daniel Schneller
1
嘿,这里是JWFolders的作者。我写了那段代码一段时间了,它肯定可以使用一些优化,但主要瓶颈在于CALayer-renderInContext:调用,这个调用无法进行优化。我希望有一种方法可以将这个库泛化,以避免截屏,但不幸的是目前还没有办法做到这一点。 - sudo rm -rf
2个回答

1
为了解决这个问题,我会放弃使用库,并让iOS在没有屏幕截图或其他技巧的情况下移动这些显示元素。在点击时,使被点击的图标保持正常外观,同时将其他所有图标变暗。从顶部到被点击的图标所在行的末尾找到集合视图的内容。创建两个新的集合视图 - 一个包含顶部一半,包括您点击的图标,另一个包含其余部分,即下面的部分。将这些视图分开动画以为文件夹视图腾出空间。
文件夹视图是另一个UICollectionView,出现在创建的间隙中。在主视图中,根据抽屉是否打开或关闭,有一个或三个视图呈现。我可能会考虑创建一个带有集合视图的视图控制器,并使用视图控制器包含来管理所有三个视图。您完全控制这些视图的呈现方式,因此可以同时向上和向下动画顶部和底部视图,以显示Springboard中的文件夹视图。
当所有这些都起作用后,您可以开始进行泛化并开始做出决定,例如如果图标位于屏幕下方,则将被点击的图标作为底部集合的一部分,并在上方显示文件夹。
(我犹豫回答这个问题,因为有很多赞,但没有答案,所以我可能错过了什么 - 但这就是我开始尝试实现Springboard效果的方式。)

谢谢您的(第一个)回答 :) 我不认为您漏掉了什么。我问这个问题是因为我希望避免在多个集合视图中进行动画等操作,并且更喜欢一些“更简单”的方法,也可以在其他地方使用。但是我得出结论,这可能是唯一可行的方法,尽管它需要更多的工作。我们目前正在采用类似于您建议的方法。 - Daniel Schneller

0
为了相对简单地解决这个问题,您可以尝试将文件夹制作为一个简单的UICollectionView子类,然后在相册单元格被点击时插入该单元格。
在集合视图的数据源中,您需要返回不同的大小等信息以用于文件夹单元格。
在文件夹中,您需要创建文件夹集合视图,但要避免将文件夹单元格作为单元格文件夹集合视图的数据源。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接