55

好的,我认为是时候在互联网上为这个问题建立一个官方位置了:How to make a UIScrollViewphotoviewer with paging and zooming。UIScrollView欢迎我的黑客伙伴。

UIScrollView启用了分页功能,并且UIImageViews像内置照片应用程序一样显示。(这听起来是不是很熟悉?)

我在github上找到了以下项目:

https://github.com/andreyvit/ScrollingMadness/wiki

它显示了如何在启用分页时在滚动视图中实现缩放。如果其他人尝试这样做,我实际上必须删除UIScrollView子类并使用本机类,否则它不起作用。我认为这是因为 3.0 SDK 中有关滚动视图如何拦截触摸事件的更改。

所以这个想法是在您开始缩放时删除所有其他视图,并将当前视图移动到 (0, 0) 中scrollview,更新contentsize等。然后当您缩放回 1.0f 时,它会重新添加其他视图并放置一切恢复正常。

无论如何,该项目在模拟器中运行良好,但在设备上,您正在调整大小的视图有一些令人讨厌的移动,这看起来是由于我们正在更改contentsize/offset等以调整视图大小。您必须移动此视图,否则您可以通过其他视图留下的空白向左平移。

我在3.0 SDK 发行说明的“已知问题”中发现了一个有趣的说明:

UIScrollView:缩放后,内容插入被忽略,内容留在错误的位置。

这种听起来就像这里正在发生的事情。放大后,视图将移出屏幕,因为您更改了偏移量等。

我已经在这上面花了几个小时,但我正在慢慢意识到这行不通。

Three20 的照片查看器是不可能的:它太重了,而且有太多不必要的 UI 和其他行为。

内置的照片应用程序似乎有一些魔力。如果您放大图像并平移到远边缘,则当前照片会独立于旁边的照片移动,这不是您在使用标准UIScrollView.

我看过关于嵌套UIScrollView's 的讨论,但我真的不想去那里。

有没有人用标准管理过这个UIScrollView(并且在 2.2 和 3.0 SDK 中工作)?我不喜欢滚动我自己的缩放 + 弹跳 + 平移 + 分页代码。

4

8 回答 8

43

更新

因为下面的消息,我删除了我之前的答案......

对于那些没有听说过的人来说是个大新闻。Apple 已向 iphone 开发者计划的所有成员发布了 2010 年 WWDC 会议视频。讨论的主题之一是他们如何创建照片应用程序!!!他们逐步构建了一个非常相似的应用程序,并免费提供了所有代码。

它也不使用私有 api。这是示例代码下载的链接。您可能需要登录才能获得访问权限。

检查这个

而且,这里是 iTunes WWDC 页面的链接:

检查这个

于 2010-06-18T04:50:50.033 回答
32

我编写了一个简单易用的照片浏览器,名为MWPhotoBrowser。我决定创建它,因为 Three20 太重/臃肿,因为我只需要一个照片查看器。

MWPhotoBrowser 可以通过提供 UIImage 对象或文件、Web 图像或库资源的 URL 来显示一个或多个图像。照片浏览器无缝地处理来自网络的照片的下载和缓存。照片可以缩放和平移,并且可以显示可选(可自定义)的标题。浏览器还可用于允许用户使用网格或主图像视图选择一张或多张照片。

MWPhotoBrowser 截图

于 2011-03-03T17:33:48.487 回答
19

您说您已经看到有关嵌套 UIScrollViews 的讨论,但不想去那里 - 但这是要走的路!它工作起来很容易而且很好。

这本质上就是 Apple 在其 PhotoScroller 示例中所做的(以及与 Jonah 的回答相关的 2010 WWDC 演讲)。仅在这些示例中,他们添加了一大堆复杂的平铺和其他内存管理。如果您不需要平铺等,并且如果您不想浏览这些示例并尝试删除与之相关的位,那么嵌套 UIScrollViews 的基本原理实际上非常简单:

  • 创建一个外部 UIScrollView 并设置它的 pagingEnabled = true。将其添加到主视图并将其宽度和高度设置为主视图的宽度和高度。

  • 根据需要创建尽可能多的内部 UIScrollViews 图像。将它们的宽度和高度设置为主视图的宽度和高度。将它们作为子视图添加到您的外部 UIScrollView,每个相邻,从左到右。

  • 将外部 UIScrollView 的内容大小设置为并排所有内部 UIScrollView 的宽度的总和(等于 [您的主视图的宽度]*[图像数量])。

  • 将图像的 UIImageViews 添加到内部 UIScrollViews,一个 UIImageView 到每个内部 UIScrollView。将每个 UIScrollView 的内容大小设置为每个 UIImageView 的大小。

  • 为每个内部 UIScrollView 设置最小和最大缩放比例,并将每个内部 UIScrollView 的委托设置为您的视图控制器。在委托的 viewForZoomingInScrollView 中,为传递的 UIScrollView 返回相应的 UIImageView。(为此,只需将每个 UIImageViews 保存在 NSArray 中,并将相应的 UIScrollView 的 tag 属性设置为相应 UIImageView 的索引。然后您可以读取传递给 viewForZoomingInScrollView 的 UIScrollView 中的标签,并从 NSArray 返回相应的 UIImageView) .

就是这样。就像照片应用程序一样工作。

如果你有很多照片,为了节省内存,你可以只拥有两个内部 UIScrollViews 和两个 UIImagesViews。然后,您可以在它们之间动态翻转,在外部 UIScrollView 中移动它们的位置,并在用户滚动外部 UIScrollView 时更改它们的图像。它有点复杂,但原理相同。

于 2012-04-28T06:11:38.853 回答
6

我玩了一些原生照片应用程序,我想我可以自信地说他们使用的是单个 UIScrollView。赠品是这样的:放大图像,然后向左或向右拉。您将看到下一张或上一张照片。如果你用力拉,它甚至会以 1.0f 变焦翻页到下一张照片。向后翻转,之前缩放的照片也将恢复到 1.0f 缩放。

显然我没有写 Photos.app,但我会大胆猜测他们是如何做到的:

  • 一个 UIScrollView 和一个 UIScrollViewDelegate
  • 使用 UIImageView 子项填充 UIScrollView
  • 聆听scrollViewDidScroll:
  • 做一些数学运算并找出您当前所在的页面
  • 聆听viewForZoomingInScrollView:
  • 根据页面索引返回不同的视图
  • 根据内容收听scrollViewDidEndZooming:withView:atScale:并选择性地做一些抗锯齿等

如果您决定尝试一下,请告诉我它对您的效果。我很想知道你最终是如何让这个工作的。更好的是,将其发布到 github。

于 2010-02-08T17:54:41.057 回答
1

我玩了一些原生照片应用程序,我想我可以自信地说他们使用的是单个 UIScrollView。赠品是这样的:放大图像,然后向左或向右拉。您将看到下一张或上一张照片。如果你用力拉,它甚至会以 1.0f 变焦翻页到下一张照片。向后翻转,之前缩放的照片也将恢复到 1.0f 缩放。

这是错误的。我正在使用嵌套滚动视图,并获得完全相同的效果。如果您正在使用一些内存管理方案(我必须开始使用......我的页码相当高('在 2 个滚动视图中每个大约 50 个)),那么您可以使用类似于触发页面的任何机制加载/卸载以从当前页面触发页面 -1 和 +1 的缩放重置。

我怀疑苹果会在上一张照片消失后立即启动此功能。

我不明白的是如何实现页面之间的平滑滚动——在转换的那一刻总是有一个很短的挂起。不明白。我已经深入修复它 - NSInvocationOperations 是我的第一站,然后我为页面视图(保留他们的图像视图)创建了一个可重用的视图队列......仍然是这个死机。

我只有一个 NSOperationQueue 正在运行,并且我尝试过摆弄最大并发操作数。我的想法是主线程被竞争队列阻塞,或者甚至一个队列试图做很多事情......仍然是挂起。

我什至尝试创建我的媒体的超低质量版本,以防出现问题。每张图像的重量约为 10k(这些是 jpeg,请注意)......你猜对了。悬念还在。

我非常决定做我以前做过的事情,并使用 Three20 的 TTPhotoViewController。我花了几个小时浏览该代码,这总是一种很好的教育。不过,在这一点上,我真的很想知道这到底是从哪里来的,如果这样我就可以度过我无法入睡的几个小时,想知道一些不那么大脑沸腾的事情。

于 2010-02-14T17:31:34.053 回答
0

如果苹果在 SDK 中构建了一个像照片应用这样的图像查看器供我们使用,那肯定会很好。我目前正在使用three20,效果很好。但是,当您真正想要的只是照片查看器时,要随身携带很多额外的东西。

于 2010-06-11T21:55:24.327 回答
0

我为此写了一个代码,可以作为参考

  1. 加载当前视图 scrollview 和 imageview .. 并且对于当前视图旁边的屏幕,只有 imageview

  2. 当前页面加载时删除所有视图以节省内存,这对许多照片项目都有好处

  3. 使用标签区分不同的滚动视图

第一页_xxxx 滑动xxx飞涨

下载链接点击这里

于 2012-01-24T10:12:58.577 回答
-1

看看https://github.com/facebook/three20/blob/master/src/Three20UI/Headers/TTPhotoViewController.h不知道这是否是你要找的

于 2009-07-28T22:37:27.253 回答