我有一个UIPageViewController
,其视图控制器包含UIScrollView
,其中包含UIImageView
。在加载的视图控制器viewWillAppear
中,如果旋转视图,则边界不正确。这是我根据this根据图像大小动态定位图像视图的地方。我尝试使用(void)viewDidLayoutSubviews
,但我需要调用[self.view layoutSubviews]
或者我收到断言错误。当我添加它,然后我不能再缩放图像视图。您可以看到它尝试缩放但调整大小到最小缩放。
我对自动布局完全不熟悉,并试图看看我是否遗漏了一些东西。
我当前的修复涉及检查框架的边界以查看方向是否与边界匹配。如果是这样,那么我按原样使用边界。如果没有,那么我在计算中切换高度和宽度。
我想知道如何正确使用viewDidLayoutSubviews
而不会剥夺我放大图片视图的能力。
从两个答案中,看起来viewDidLayoutSubviews
可能是布局视图的错误位置。我试图找到应该在哪里完成并让视图知道它们的边界和方向,但在它们在屏幕上可见之前。从我的阅读中,我认为那是viewDidLayoutSubviews
,但似乎使用它可能导致无限循环。
答案 0 :(得分:6)
从两个答案中,看起来像viewDidLayoutSubviews可能是 错误的地方布局视图。我试图找到它应该在哪里 完成并让观点了解他们的界限和方向但是 在屏幕上显示之前。
我会继承UIScrollView
并覆盖layoutSubviews
,只有在需要时以及所有变量(方向,大小等)都具有适当的值时,系统才会为您调用。
答案 1 :(得分:2)
首先,你不应该自己打电话给-layoutSubviews
。来自UIView
documentation for that method:
您不应该直接调用此方法。如果你想强迫一个 布局更新,请先调用setNeedsLayout方法 到下一个图纸更新。如果你想更新你的布局 立即查看,调用layoutIfNeeded方法。
即使没有警告,从-viewDidLayoutSubviews
调用该方法似乎是一个问题的处方 - 调用-viewDidLayoutSubviews
来通知您的视图控制器它的视图只是将其设置为子视图,因此调用{{ 1}}可能很容易导致循环。
在加载的视图控制器viewWillAppear中,如果旋转视图,则边界不正确。
请记住,调用[self.view layoutSubviews]
时,视图hasn't yet been added to a view hierarchy。鉴于此,您当前的方法似乎并不是一个糟糕的方法。该视图尚未设置其边界(因为它尚未添加),因此您可以确定边界的内容并使用它来设置视图。另一个可能更好的方法是使用-viewWillAppear
,因为你的视图将在那时被添加,并且到那时应该有正确的界限。
当我添加它时,我无法再缩放图像视图。您可以 看到它试图缩放,但调整大小回到最小变焦。
听起来,当您放置图像视图时,您并未考虑缩放状态。确保-viewDidAppear
中的代码不能否定滚动视图正在执行的工作。
你根本不需要改变图像视图的位置 - 这正是自动布局擅长的那种东西。我注意到您作为示例使用的ImageScrollViewController.m文件并未更改图片视图的位置。
答案 2 :(得分:1)
我不完全确定您的视图层次结构,但是如果您有一个包含UIScrollView的视图控制器的视图控制器,此答案将说明如何执行此操作。 (所述视图控制器稍后在UIPageViewController中显示,但这与此无关)。
在视图控制器中覆盖控制滚动视图的以下方法:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
CGRect bounds = self.view.bounds;
self.scrollView.frame = bounds;
//
// Calculate a rect for your image view according to bounds
//
self.imageView.frame = calculatedFrame;
}
问题是您的视图将在滚动/缩放期间进行布局,如果您将视图放在控制scrollView的视图控制器的viewDidLayoutSubviews中,则每次用户滚动或缩放时都会对其进行定位。
我怀疑你的视图控制器可能直接控制UIScrollView(而不是控制具有UIScrollView子视图的视图),在这种情况下,只需删除self.scrollView.frame = self.bounds
行。
您永远不应该从viewDidLayoutSubviews调用[self.view layoutSubviews]。事实上,你根本不应该打电话给那个功能。如果您需要更新布局,请调用[self.view setNeedsLayout]。但是当您的视图执行了其layoutSubviews时,会自动调用viewDidLayoutSubviews。这意味着如果你从那里调用那个函数,你将得到一个无限循环。