UIScrollView框架始终为CGRectZero

时间:2014-11-04 17:45:41

标签: ios objective-c xcode uiscrollview

我有一个标准UIView的笔尖,我还包含UIScrollView作为IBOutlet(是的,它被连接起来),而不是作为子视图主要的UIView,但仅仅是自己的。 Autolayout已关闭。滚动视图有几个子视图,并且比主视图大。在viewWillAppear:中,我将UIScrollView的内容大小设置为其当前帧大小,然后将其框架设置为主视图的大小,并将其添加为主视图的子视图。 / p>

不幸的是,没有任何东西出现。当我NSLog UIScrollView的框架时,它会以{0, 0, 0, 0}CGRectZero)的形式返回。我觉得这很奇怪,所以我回去尝试记录框架,然后才对其进行任何更改。还是零。在对任何视图元素执行任何操作之前,将其记录在viewDidLoad中。还是零。 (我的笔尖中的FWIW,框架为{0, 0, 320, 896}

我的几个控制器出现了这个问题,但它似乎很受欢迎。有时它可以工作,有时我得到空框架。通常情况下,从头开始重新创建所有内容似乎都可以解决问题,但我不知道为什么,因为我两次都设置了相同的内容。

运行Xcode版本6.1(6A1052d),iOS SDK 8.1,部署目标为7.0

如果有任何其他可能有帮助的相关信息,请告诉我。


编辑1:要解决有关我的UIScrollView是"子视图"的问题,以下是我在文档大纲中查看heirarchy的视图:
Document Outline
正如您所看到的,UIScrollView是一个"子视图"视图控制器,但不是"主要"的子视图。 UIView,其中包含控制器view插座。


编辑2:更多图像和一些代码。这里可以更好地了解我的笔尖是如何设置的:
Nib Screenshot

我将scrollView添加到主UIView,如下所示:

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

    scrollView.contentSize = scrollView.frame.size;
    scrollView setFrame:CGRectMake(0, 100, self.view.frame.size.width, self.view.frame.size.height - 100); // I slightly modified this because there are other variables that determine its Y position and height
    [self.view addSubview:scrollView]
}

但我仍然认为任何代码都不重要 - 无论出于何种原因,我的UIScrollView都会回来nil。如果我在笔尖中创建了视图,插座连接正确,视图如何仍为零?我通过initWithNibName创建我的控制器我尝试清理项目,删除应用并重新安装。

2 个答案:

答案 0 :(得分:0)

首先,您可能需要考虑使用autolayout。一旦您进行投资以了解它是如何工作的,它就会使事情更容易很多。使用带有autolayout的UIScrollview查看此Apple doc

如果这不是一个选项,问题是你在循环中的错误点设置了scrollView。 scrollView需要有机会自我解决。当你点击viewWillAppear时,你错过了子视图布局。

所以,你可以尝试:

  1. 在willLayoutSubviews中配置scrollView并设置其setNeedsLayout属性。

  2. 在viewWillAppear中的scrollView上显式调用layoutIfNeeded。这个想法是强制另一个子视图布局循环。但是,我并不是百分之百确定它会起作用 - 在那一点上可能为时已晚。

  3. 请注意,在查看viewDidAppear之前,不会确定主视图(self.view)的大小。它在viewWillAppear中并不总是正确的。因此,您的设置存在问题:在您知道自己的视图大小之前,您无法真正设置您的scrollView,但是您不知道这一点,直到为时已晚!您可能希望重新设计以避免这种依赖性。

答案 1 :(得分:0)

最佳猜测答案,以及一些评论:

  • Nibs只是序列化的对象树。您可以根据需要拥有尽可能多的视图。问题(大问题!)是,如果他们没有与retain他们的网点“连接”,那么在某些时候你会丢失这些参考文献。

由于您的UIScrollView不是Nib上主视图控制器视图的子视图,因此它不会保留(视图保留其子视图)。因此,您可以将其保留在视图控制器上。

我的猜测是,在您尝试在View Controller中设置框架时,滚动视图已经消失。我不确定你什么时候这样做,但它可能是在一些运行循环后,所以未释放的滚动视图被解除分配。

解决方法:

  1. 使用强大的属性(IBOutlet)代替@property (strong, nonatomic) IBOutlet UIScrollView *scrollView的变量。
  2. __strong限定符添加到变量。
  3. UIScrollView添加为 nib中的子视图,因此当反序列化对象树时,它已被其父级保留。
  4. 鉴于您故意将UIScrollView放在主视图层次结构之外,我假设您不想要选项3,所以我将只使用1。