繁体   English   中英

Autolayout中的viewDidLayoutSubviews,在UIPageViewController上旋转

[英]viewDidLayoutSubviews in Autolayout with rotation on UIPageViewController

我有一个UIPageViewController其视图控制器包含一个UIScrollView ,其中包含一个UIImageView 在加载的视图控制器viewWillAppear ,如果旋转视图,则边界不正确。 这就是我试图动态地基于根据所述图像的尺寸的图像视图定位 我试图使用(void)viewDidLayoutSubviews但我需要调用[self.view layoutSubviews]或者我得到一个断言错误。 当我添加它,然后我不能再缩放图像视图。 您可以看到它尝试缩放但调整大小到最小缩放。

我对自动布局完全不熟悉,并试图看看我是否遗漏了一些东西。

我目前的修复涉及检查框架的边界以查看方向是否与边界匹配。 如果是这样,那么我按原样使用边界。 如果没有,那么我在计算中切换高度和宽度。

我想知道如何正确使用viewDidLayoutSubviews而不会剥夺我放大图像视图的能力。

从两个答案中,看起来viewDidLayoutSubviews可能是布局视图的错误位置。 我试图找到应该在哪里完成并让视图知道它们的边界和方向,但在它们在屏幕上可见之前。 从我的阅读,我认为这是viewDidLayoutSubviews但似乎使用可能会导致无限循环。

从两个答案中,看起来viewDidLayoutSubviews可能是布局视图的错误位置。 我试图找到应该在哪里完成并让视图知道它们的边界和方向,但在它们在屏幕上可见之前。

我将子类化UIScrollView并覆盖layoutSubviews ,系统将仅在需要时以及所有变量(方向,大小等)具有适当的值时为您调用。

首先,你不应该自己调用-layoutSubviews 从该方法UIView 文档

您不应该直接调用此方法。 如果要强制进行布局更新,请在下次绘图更新之前调用setNeedsLayout方法。 如果要立即更新视图的布局,请调用layoutIfNeeded方法。

即使没有警告,从-viewDidLayoutSubviews调用该方法似乎也是问题的一个方法 - -viewDidLayoutSubviews来通知您的视图控制器它的视图只是将其设置为子视图,因此调用[self.view layoutSubviews]可能很容易导致环。

在加载的视图控制器viewWillAppear中,如果旋转视图,则边界不正确。

请记住,当-viewWillAppear时,视图尚未添加到视图层次结构中 鉴于此,您的当前方法似乎并不坏。 视图尚未设置其边界(因为它尚未添加),因此您可以确定边界的内容并使用它来设置视图。 另一个可能更好的方法是使用-viewDidAppear ,因为你的视图将在那时添加,并且应该具有正确的边界。

当我添加它,然后我不能再缩放图像视图。 您可以看到它尝试缩放但调整大小到最小缩放。

听起来您在放置图像视图时没有考虑缩放状态。 确保-viewDidLayoutSubviews中的代码不会否定滚动视图正在执行的工作。

您根本不需要更改图像视图的位置 - 这正是自动布局擅长的那种。 我注意到您作为示例使用的ImageScrollViewController.m文件不会更改图像视图的位置。

我不完全确定您的视图层次结构,但是如果您有一个包含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。 这意味着如果从那里调用该函数,您将获得无限循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM