好的,我认为现在是时候在互联网上找到这个问题的正式位置了:如何使用分页和缩放制作UIScrollView
照片查看器。欢迎我的同事UIScrollView
黑客。
我有一个启用了分页的UIScrollView
,我正在显示内置照片应用的UIImageViews
。 (这听起来很熟悉吗?)
我在github上找到了以下项目:
http://wiki.github.com/andreyvit/ScrollingMadness
其中显示了启用分页时如何在滚动视图中实现缩放。如果其他人尝试这一点,我实际上必须删除UIScrollView
子类并使用本机类,否则它不起作用。我认为这是因为3.0 SDK中的变化与滚动视图拦截触摸事件的方式有关。
因此,想法是在开始缩放时删除所有其他视图,并将当前视图移动到scrollview
中的(0,0),更新contentsize
等等。然后当你缩放回1.0f它会将其他视图添加回来并将所有内容整理回来。
无论如何,该项目在模拟器中运行良好,但在设备上有一些令人讨厌的视图移动正在调整大小,这看起来像是因为我们正在更改contentsize
/ {{1对于要调整大小的视图等。您必须移动此视图,否则您可以向左平移其他视图留下的空白区域。
我在3.0 SDK release notes的“已知问题”中找到了一个有趣的注释:
UIScrollView:缩放后,内容插入将被忽略,内容将保留在错误的位置。
这种听起来像是在这里发生的事情。放大后,视图将在屏幕外移动,因为您已更改了偏移等。
我已经花了好几个小时就已经花了好几个小时,我正在慢慢地意识到这不会起作用。
Three20的照片浏览器是不可能的:它太重了,并且有太多不必要的UI和其他行为。
内置的Photo应用程序似乎有些神奇。如果您放大图像并平移到远边,则当前照片将独立于其旁边的照片移动,这与使用标准offset
进行尝试时不同。
我见过有关嵌套UIScrollView
的讨论,但我真的不想去那里。
是否有人使用标准UIScrollView
进行管理(并在2.2和3.0 SDK中使用)?我不喜欢滚动我自己的缩放+反弹+平移+分页代码。
答案 0 :(得分:43)
<强> 更新 强>
由于以下新闻,我删除了之前的答案...
对于那些没有听过的人来说是个大新闻。 Apple已向iphone开发者计划的所有成员发布了2010 WWDC会话视频。讨论的主题之一是他们如何创建照片应用程序!他们逐步构建一个非常相似的应用程序,并使所有代码免费提供。
它也不使用私人api。这是示例代码下载的链接。您可能需要登录才能获得访问权限。
并且,这是iTunes WWDC页面的链接:
答案 1 :(得分:32)
我写了一个名为MWPhotoBrowser的简单易用的照片浏览器。我决定创建它,因为Three20太沉重/臃肿,因为我需要的只是一个照片查看器。
MWPhotoBrowser可以通过提供UIImage对象或URL到文件,Web图像或库资源来显示一个或多个图像。照片浏览器可以无缝地处理来自网络的照片下载和缓存。可以缩放和平移照片,并可以显示可选(可自定义)的标题。浏览器还可用于允许用户使用网格或主图像视图选择一张或多张照片。
答案 2 :(得分:19)
你说你见过有关嵌套UIScrollViews的讨论,但不想去那里 - 但这是要走的路!它工作轻松而且很好。
这基本上是Apple在其PhotoScroller示例中所做的事情(以及与Jonah的答案相关联的2010年WWDC演讲)。仅在这些示例中,他们添加了一大堆复杂的平铺和其他内存管理。如果您不需要平铺等,如果您不想浏览这些示例并尝试删除与其相关的位,嵌套UIScrollViews的基本原则实际上非常简单:
创建外部UIScrollView并设置其pagingEnabled = true。将其添加到主视图中,并将其宽度和高度设置为主视图的宽度和高度。
根据需要创建尽可能多的内部UIScrollViews。将它们的宽度和高度设置为主视图的宽度和高度。将它们作为子视图添加到外部UIScrollView中,每个视图从左到右依次存在。
将外部UIScrollView的内容大小并排设置为所有内部UIScrollViews的宽度总和(等于[主视图的宽度] * [图像数])。
将图像的UIImageViews添加到内部UIScrollViews,每个内部UIScrollView都有一个UIImageView。将每个UIScrollView的内容大小设置为每个UIImageView的大小。
为每个内部UIScrollView设置最小和最大缩放比例,并将每个内部UIScrollView的委托设置为View Controller。在委托的viewForZoomingInScrollView中,为传递的UIScrollView返回相应的UIImageView。 (为此,只需将每个UIImageViews保存在NSArray中,并将相应的UIScrollView的标记属性设置为相应UIImageView的索引。然后,您可以读取传递给viewForZoomingInScrollView的UIScrollView中的标记,并从NSArray返回相应的UIImageView)
就是这样。像照片应用程序一样工作。
如果您有很多照片,为了节省内存,您可以拥有两个内部UIScrollViews和两个UIImagesViews。然后,您可以在它们之间动态切换,在外部UIScrollView中移动它们的位置,并在用户滚动外部UIScrollView时更改它们的图像。它有点复杂,但原理相同。
答案 3 :(得分:6)
我做了一些玩本机照片应用程序,我想我可以放心地说他们正在使用单个UIScrollView。赠品是这样的:放大图像,然后向左或向右拉。您将看到下一张或上一张照片。如果你足够努力,它甚至会以1.0f变焦页面翻到下一张照片。向后翻转,之前放大的照片也将恢复到1.0f变焦。
很明显我没有写过Photos.app,但我会猜测他们是如何做到的:
scrollViewDidScroll:
viewForZoomingInScrollView:
scrollViewDidEndZooming:withView:atScale:
并根据内容选择执行一些抗锯齿等工作如果你决定尝试一下,请告诉我它是如何运作的。我很想知道你最终是如何让这个工作的。更好的是,将它发布到github。
答案 4 :(得分:1)
我做了一些游戏 原生照片应用程序,我想我可以 他们有信心地说他们正在使用 单个UIScrollView。赠品是 这个:放大图像,然后拉到 左边或右边。你会看到的 下一张或上一张照片。如果你拉 很难,它甚至会翻页 下一张照片1.0f zoom。翻转并且 之前放大的照片将是 回到1.0f变焦。
这是错误的。我正在使用嵌套的滚动视图,并获得完全相同的效果。如果你正在使用一些内存管理方案(我必须开始使用...我的页码相当高('在2个scrollViews中各占50个)),那么你可以使用类似于你触发页面的任何机制加载/卸载以从当前页面触发页面-1和+1的缩放重置。
我怀疑苹果在上一张照片消失后立即关闭了它。
我不明白的是如何实现页面之间的平滑滚动 - 转换时总是有一个非常短的挂起。不明白。我已经非常深入地修复它 - NSInvocationOperations是我的第一站,然后我为页面视图创建了一个可重用的视图队列(保留了它们的图像视图)......仍然这个挂起了。
我只有一个NSOperationQueue正在运行,我试图摆弄最大并发操作数。我的想法是主线程被竞争的队列阻塞,或者甚至可能是一个队列试图做很多......仍然是悬挂。
我甚至尝试创建我的媒体的超低质量版本,以防出现问题。每张图像的重量都在10k左右(这些是jpegs,请注意)......你猜对了。悬挂仍在那里。
我几乎决心做我之前做过的事情并使用Three20的TTPhotoViewController。我花了几个小时浏览代码,这总是很好的教育。不过,在这一点上,我真的很想知道这个问题来自哪里,如果只是这样的话,我可以花费我的睡眠时间来思考一些不那么大脑沸腾的事情。
答案 5 :(得分:0)
答案 6 :(得分:0)
我为此编写代码,可以作为参考
加载当前视图scrollview和imageview .. 对于当前视图旁边的屏幕,只有imageview
当前页面加载时删除所有视图以节省内存,这对很多照片项目都很有用
使用标记来区分不同的scrollview
_ {XXXX {0}} {XXX {0}}
答案 7 :(得分:-1)