清除分页 UIScrollView 中的自动旋转转换
Posted
技术标签:
【中文标题】清除分页 UIScrollView 中的自动旋转转换【英文标题】:Clean autorotation transitions in a paging UIScrollView 【发布时间】:2010-07-23 21:33:04 【问题描述】:我有一个分页 UIScrollView,用户可以在其中水平浏览图像,例如 Apple 的 Photos.app。这行得通,但现在我正在尝试添加旋转支持。
我的视图旋转正常,并设法正确设置 contentSize、边界和子视图的框架以适应不同的方向。所以旋转前后,一切正常。
但是,过渡本身很尴尬。第一个图像完美旋转,好像旋转轴位于图像的死点(滚动视图框架)。第二幅图像“摆动”,因为旋转轴在同一个位置:第一幅图像的中心。我离第一张图片越远,“摆动”越快。
我可以通过在旋转之前覆盖一个不透明的 UIView 并在之后隐藏它来掩盖这一点。但这是一个黑客。必须有一种优雅的方式来做到这一点......
【问题讨论】:
【参考方案1】:坦率地说,我不知道你在做什么,因为你根本没有向我们展示太多东西。
但是!
我在滚动视图中创建了一个包含几个视图的示例项目,它工作正常。随意挑选它,如你所愿。它通过创建 5 个视图并将它们添加到滚动视图来工作。然后在第一次设置这些视图之后,并且每次应用程序旋转时,它都会调用我的方法alignSubviews
将它们布置在正确的页面位置并使它们与滚动视图相同大小,同时更新滚动查看contentSize
。在旋转发生之前,它会跟踪滚动视图当前所在的页面,然后在旋转期间将其重置为该页面(因为页面大小必须更改)。
Download "Rotolling"!
【讨论】:
很好的例子!我没有发布任何代码,因为我知道我所拥有的需要报废。这个故事的寓意是,如果我发现自己到处手动设置和重置视图框架,那我就错了。 谢谢你的好例子。需要为在 ios 6 上成功启动做一个修复:[window setRootViewController:viewController];到应用程序:didFinishLaunchingWithOptions 方法。 感谢您提供了一个很好的例子,解决了我的一个大问题!【参考方案2】:我记下了这些附加信息,以供以后参考。 我用@jtvandes 解决方案的想法解决了这个问题。 但是,就我而言,这些实现就足够了。强制布局再次打破了我的看法。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
currentPageOffset = [hostingScrollView contentOffset].x / [hostingScrollView bounds].size.width;
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
// Layout changed instantly at this time.
// So we have to force to set offset instantly by setting animation to NO.
[hostingScrollView setContentOffset:CGPointMake([hostingScrollView bounds].size.width * currentPageOffset, 0.0f) animated:NO];
【讨论】:
【参考方案3】:听起来你正在应用魔法,需要在屏幕上的正确位置以错误的方式获得旋转版本。
由于您没有共享任何代码,以下只是猜测。据推测,您应用了旋转和平移。它听起来就像您正在旋转UIScrollView
的内容。做到这一点将是棘手的。没有代码很难说任何结论性的东西,但如果你只有 1 次旋转和 1 次平移,那么你做错了。您需要将当前视图平移到枢轴点、旋转并向后平移。否则平移将是旋转的一部分(因此是大摆动)。
您最好旋转UIScrollView
本身。它将始终位于具有定义中心的定义位置(即:屏幕)。然后内容将随之旋转。
【讨论】:
【参考方案4】:一个行之有效的简单解决方案是在 UIScrollView 的 contentSize 发生更改时注册通知,然后在此时更新 contentOffset。
在你的视图加载方法中添加这一行:
[self addObserver:theScrollView forKeyPath:@"contentSize" options:0 context:nil];
在你的视图卸载方法中添加这一行:
[self removeObserver:self forKeyPath:@"contentSize"];
捕捉通知:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
theScrollView.contentOffset = page * theScrollView.bounds.width;
【讨论】:
以上是关于清除分页 UIScrollView 中的自动旋转转换的主要内容,如果未能解决你的问题,请参考以下文章