gpt4 book ai didi

objective-c - iOS5、UIScrollView 和 layoutSubviews 行为

转载 作者:技术小花猫 更新时间:2023-10-29 10:39:38 25 4
gpt4 key购买 nike

在我的应用程序中(代码非常类似于来自 WWDC10 的 Apple 的 PhotoScroller 演示),我有一个 UIScrollView。在 ScrollView 中,我用如下代码覆盖了 layoutSubviews:

- (void) layoutSubviews {
[super layoutSubviews];
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
...
}

在 iOS 4.x 中,如果应用程序以横向模式启动(用户横向握住它),那么 layoutSubviews 会被调用两次(非常快)。第一次调用时,boundsSize 的尺寸表明它是纵向的,但紧接着它被再次调用并且 self.bounds.size 返回尺寸表明设备处于横向并且我的布局计算工作正常。

在 iOS 5.x 中,layoutSubviews 只被调用一次,bounds.size 返回表示纵向的尺寸,它没有得到第二次调用,所以我所有的计算代码都搞砸了。

如果用户以物理方式旋转设备,则会调用 layoutSubviews 并正常工作——因此用户以横向启动应用程序(绘制不正确),旋转到纵向(正确绘制)然后旋转回横向(现在正确绘制) .

这是我缺少的 layoutSubviews 的第二次“自动”调用。

还有其他人注意到这一点或有任何建议吗?

更新:

我确实在 iOS 5 的 UIKit 发行说明中找到了这个,但我不确定它是否相关,甚至不确定此更改的影响是什么。

Rotation callbacks in iOS 5 are not applied to view controllers that are presented over a full screen. What this means is that if your code presents a view controller over another view controller, and then the user subsequently rotates the device to a different orientation, upon dismissal, the underlying controller (i.e. presenting controller) will not receive any rotation callbacks. Note however that the presenting controller will receive aviewWillLayoutSubviews call when it is redisplayed, and the interfaceOrientation property can be queried from this method and used to lay out the controller correctly.

进一步更新:

使用 [UIView recursiveDescription] 转储 View 层次结构,我得到以下输出:

iOS 4(正常工作):

纵向:

2011-12-19 15:57:06.400 stroom[10889:11603] <0x5e7f9b0 stroomViewController.m:(402)> <UIView: 0x6a6f2f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x6a659d0>>
| <UIScrollView: 0x5e911e0; frame = (-20 0; 808 1024); clipsToBounds = YES; autoresize = LM+W+RM+TM+H+BM; layer = <CALayer: 0x5e91370>; contentOffset: {0, 0}>
| | <stroomFullScreenPhotoScrollView: 0x5ea1010; baseClass = UIScrollView; frame = (20 0; 768 1024); clipsToBounds = YES; layer = <CALayer: 0x5ea0940>; contentOffset: {0, 0}>
| | | <UIImageView: 0x5ea2600; frame = (0 224; 768 576); transform = [0.75, 0, 0, 0.75, 0, 0]; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5ea0890>>

风景:

2011-12-19 15:57:34.522 stroom[10889:11603] <0x5e7f9b0 stroomViewController.m:(402)> <UIView: 0x6d96c30; frame = (0 0; 768 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x6d66440>>
| <UIScrollView: 0x5e9eb70; frame = (-27 0; 1078 768); clipsToBounds = YES; autoresize = LM+W+RM+TM+H+BM; layer = <CALayer: 0x5eadde0>; contentOffset: {0, 0}>
| | <stroomFullScreenPhotoScrollView: 0x6dab850; baseClass = UIScrollView; frame = (20 0; 1038 768); clipsToBounds = YES; layer = <CALayer: 0x6dab2e0>; contentOffset: {0, 0}>
| | | <UIImageView: 0x5e97f70; frame = (0 224; 1024 768); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5e97fa0>>

iOS 5(运行不正常):

纵向:

 2011-12-19 15:55:59.530 stroom[10850:16103] <0x848b520 stroomViewController.m:(402)> <UIView: 0xa884710; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0xa8849a0>>
| <UIScrollView: 0xa883820; frame = (-20 0; 808 1024); clipsToBounds = YES; autoresize = LM+W+RM+TM+H+BM; layer = <CALayer: 0xa883a80>; contentOffset: {0, 0}>
| | <stroomFullScreenPhotoScrollView: 0x8699630; baseClass = UIScrollView; frame = (20 0; 768 1024); clipsToBounds = YES; layer = <CALayer: 0x8699360>; contentOffset: {0, 0}>
| | | <UIImageView: 0x869a7c0; frame = (0 0; 768 576); transform = [0.75, 0, 0, 0.75, 0, 0]; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x869a800>>

风景:

 2011-12-19 15:56:32.521 stroom[10850:16103] <0x848b520 stroomViewController.m:(402)> <UIView: 0x8498530; frame = (0 0; 768 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x8498560>>
| <UIScrollView: 0x849ead0; frame = (-27 0; 1077 768); clipsToBounds = YES; autoresize = LM+W+RM+TM+H+BM; layer = <CALayer: 0x848f390>; contentOffset: {808, 0}>
| | <stroomFullScreenPhotoScrollView: 0x81e4b80; baseClass = UIScrollView; frame = (828 0; 768 1024); clipsToBounds = YES; layer = <CALayer: 0x81e7dc0>; contentOffset: {0, 0}>
| | | <UIImageView: 0x81e5090; frame = (0 0; 768 576); transform = [0.75, 0, 0, 0.75, 0, 0]; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x81e5010>>

从这些我可以看出,iOS 5 中 UIScrollView 的 contentOffset 看起来不正确,横向框架在 iOS 5 中的尺寸不正确,而在 iOS 4 中它们似乎具有正确的尺寸。

最佳答案

最终,我偶然发现了这个问题的解决方案。我会在这里提供答案,因为它可能对其他人有帮助。

我的解决方案是在我的 View Controller 上实现 - (void)viewWillAppear:(BOOL)animated 方法。我没有,我的所有设置逻辑都在 - (void) viewDidLoad 方法中。

特别是,我实现了以下内容:

- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];

CGRect bounds = pagingScrollView.bounds; // <=== this was the key

// ... use the bounds in my view setup logic
}

在我看来,iOS 5 发生了变化(与之前的操作系统版本相比)。当设备处于横向时加载 View 时, View 上的 bounds 属性不会反射(reflect)方向转换,直到 viewWillAppear。以前,在 viewDidLoad 中,边界值对我来说是正确的,但是将 bounds 属性的计算和读取从那里移到 viewWillAppear 中做了把戏。

当我进行测试时,在 iOS4 中也一切正常。

也许,我应该一直阅读 viewWillAppear 中的 bounds 属性,这很可能是更正确 的行为。但是,iOS4 和 iOS 5 之间发生了一些变化,我无法找到相关文档。

`

关于objective-c - iOS5、UIScrollView 和 layoutSubviews 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7809598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com