viewDidLayoutSubviews在touchesBegan之后调用 – 一次又一次

在一个iPhone的文字游戏中,我有一个UIScrollView (持有UIImageView )和7个可拖动的自定义UIView最初放置在底部(和滚动视图外):

应用截图

在单个ViewController.m中,我已经覆盖了viewDidLayoutSubviews所以它总是设置zoomScale的滚动视图 – 使UIImageView完全填充屏幕宽度的100%。

这适用于纵向和横向模式。 而当应用程序刚刚开始:

肖像

景观

然而, 我的问题是,当我第一次捏/放大/双击滚动视图,然后移动七个Tile.m视图之一:

突然(不是每次都)在touchesBegan之后调用viewDidLayoutSubviews

这将重置滚动视图的缩放 – 意外地为用户。

我的问题是,如果有什么方法来禁用这种行为?

当它的子UIView被触摸/拖动时,是否有可能阻止父viewDidLayoutSubviews调用?

更新:

我已经将zoomScale设置代码从viewDidLayoutSubviews到了didRotateFromInterfaceOrientation并且滚动视图缩放现在可以,但是当(不是总是)拖动一个Tile时,它的contentOffset被重置为{0,0} – 即滚动视图突然跳转,该应用程序无法使用。

添加以下内容到viewDidLoad没有帮助:

 if ([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]) self.automaticallyAdjustsScrollViewInsets = NO; 

只要系统在视图( layoutSubviews )上执行布局,就会调用viewDidLayoutSubviews 。 这可以被称为多种原因; 你可以inheritance你的视图,实现一个空的layoutSubviews方法(不要忘记调用super实现!),并在那里放置一个断点,看看是谁造成的布局。 你也可能想要实现setNeedsLayoutlayoutIfNeeded ,并在那里放置断点以供调查,因为这些触发器布局在后续的runloops上。

但是你永远无法阻止布局。 系统会在您无法控制的许多场合执行布局。 例如,如果用户拨打电话,存在电话应用程序并返回到您的应用程序; 由于窗口的边界和框架已经改变,布局被触发。 通话结束; 布局再次被触发,因为现在窗口已经回到以前的大小。

您应该负责确定何时设置缩放比例。 例如,如果用户启动一个手势,即使执行了布局,也应该指示您的代码不要执行更改。