在touchesBegan之后再次调用viewDidLayoutSubviews

编程入门 行业动态 更新时间:2024-10-26 15:22:29
本文介绍了在touchesBegan之后再次调用viewDidLayoutSubviews-一次又一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在我已经覆盖了 viewDidLayoutSubviews ,以便它始终设置滚动视图的 zoomScale -使 UIImageView 恰好填充屏幕宽度的100%

这很好用-适用于纵向和横向模式.而当应用程序刚刚启动时:

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

突然(并非每次),在 touchesBegan 之后调用 viewDidLayoutSubviews .

这将重置滚动视图的缩放-出乎用户意料之外.

我的问题是是否有任何方法可以禁用此行为?

当其子级 UIView 被触摸/拖动时,是否可以阻止父级的 viewDidLayoutSubviews 调用?

更新:

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

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

if([[自身responsesToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets :)]))self.automaticallyAdjustsScrollViewInsets = NO;

每当系统在视图上执行布局( layoutSubviews )时,都会调用

解决方案

viewDidLayoutSubviews .可以出于多种原因来称呼它.您可以将视图子类化,实现一个空的 layoutSubviews 方法(不要忘记调用 super 实现!),然后在其中放置一个断点,以查看导致布局的原因.您可能还想实现 setNeedsLayout 和 layoutIfNeeded ,并在其中放置断点以进行调查,因为这些触发点会在后续运行循环中触发布局.

但是您将永远无法阻止布局.系统会在您无法控制的许多情况下执行布局.例如,如果用户拨打电话,则该电话应用程序存在并返回到您的应用程序;因为窗口的边界和框架已更改,所以触发了布局.通话结束;再次触发布局,因为现在窗口返回到先前的大小.

您应该负责确定何时设置缩放比例.例如,如果用户开始手势,则即使已执行布局,您也应向代码发出信号以不执行更改.

In an iPhone word game I have an UIScrollView (holding UIImageView) and 7 draggable custom UIViews placed initially at the bottom (and outside the scroll view):

In the single ViewController.m I have overwritten viewDidLayoutSubviews so that it always sets the zoomScale of the scroll view - to have the UIImageView fill exactly 100% of the screen width.

This works well - for portrait and landscape modes. And when the app is just started:

My problem is however, when I first pinch/zoom/double-tap the scroll view and then move one of the seven Tile.m views:

Suddenly (not every time) viewDidLayoutSubviews is called after touchesBegan.

This resets the zoom of the scroll view - unexpectedly for the user.

My question is if there is any way to disable this behavior?

Is it possible to prevent viewDidLayoutSubviews call of the parent, when its child UIView is being touched/dragged?

UPDATE:

I've moved the zoomScale setting code from viewDidLayoutSubviews to didRotateFromInterfaceOrientation and the scroll view zoom is okay now, but its contentOffset is reset to {0,0}, when (not always) I drag a Tile - i.e. the scroll view jumps suddenly, the app is unusable.

Adding the following to viewDidLoad hasn't helped:

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

解决方案

viewDidLayoutSubviews is called whenever the system performs layout on the view (layoutSubviews). This can be called for a plethora of reasons; you can subclass your view, implement an empty layoutSubviews method (don't forget to call the super implementation!) and put a breakpoint there to see who causes the layout. You may also want to implement setNeedsLayout and layoutIfNeeded, and put breakpoints there also for your investigation, as these trigger layout on followup runloops.

But you will never be able to prevent layout. The system performs layout on many occasions which are outside of your control. For example, if a user makes a call, exists the phone app and returns to your app; a layout is triggered because the bounds and frame of the window have changed. The call ends; layout is again triggered because now the window is back to previous size.

You should be responsible for figuring out when to set the zoom scale. For example, if the user starts a gesture, you should signal your code not to perform changes, even if a layout was performed.

更多推荐

在touchesBegan之后再次调用viewDidLayoutSubviews

本文发布于:2023-11-27 23:53:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1640117.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:touchesBegan   viewDidLayoutSubviews

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!