viewWillTransitionToSize:withTransitionCoordinator:和layoutSubviews之间的交互:

时间:2017-11-14 17:38:05

标签: ios objective-c uikit

我有一个包含我通过覆盖layoutSubviews管理的子视图的视图。当然,这会在创建视图时调用以执行初始布局。我根据需要调用setNeedsLayout,以便根据应用中的状态更改对布局进行更改。一切正常。

为了处理轮换,我覆盖viewWillTransitionToSize:withTransitionCoordinator:做一些工作来准备轮换(没有任何可见;只是内部状态),然后只允许layoutSubviews按预期调用新的尺寸。这很有效。

作为对相关主题的讨论的结果,我正致力于将我的子视图的布局和动画移动到animateAlongsideTransition:completion:的调用中,该调用协调我的子视图帧的动画随着旋转动画。因此,在viewWillTransitionToSize:withTransitionCoordinator:中,我计算了所有新的帧,然后调用animateAlongsideTransition:completion:来设置帧的动画。

问题是在我的动画开始之前,layoutSubviews被调用三次。我打破了setNeedsLayout我自己的电话,所以我知道这不是造成这种情况的原因。当layoutSubviews查看其边界矩形时,它已设置为新的(旋转的)宽度和高度。因此,当我的框架设置代码作为轮换过渡的一部分被调用时,layoutSubviews已经适当地定位了视图。

我无法移除layoutSubviews因为我需要它来进行视图的初始配置以及用户与应用交互时发生的各种状态更改。我可以将其重命名为myLayoutSubviews并根据需要明确调用它(在viewDidLoad中并在进行状态更改时),但这似乎是不好的形式。

所以问题是:如何防止layoutSubviews被调用或如何检测到它是因为旋转而被调用的,并且这样做会让人感觉到#34;正确&#34} ;?当然有正确的方法来做到这一点;我无法找到它。

1 个答案:

答案 0 :(得分:0)

我遇到了类似的问题。对我来说,我必须使用变量initialLayout,该变量在初始化程序中设置为false。第一次调用layoutSubviews时,我将initialLayout设置为true

obj-c

@implementation CustomViewController {
  BOOL initialLayout;
}

init {
  self = [super initWithNibName:nil bundle:nil];
  if (self) {
    initialLayout = false;
  }
  return self; 
}

- (void)viewWillLayoutSubviews {
  [super viewWillLayoutSubviews];

  if (initialLayout == false) {
    [self firstLayout];
  }
}

-(void)firstLayout {
  // All my layout code
  initialLayout = true;
}

 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:
(id<UIViewControllerTransitionCoordinator>)coordinator {
   [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
   // All my layout code
}

迅速

class CustomViewController : UIViewController {
  var initialLayout: Bool

  init() {
    super.init(nibName: nil, bundle:nil)
    initialLayout = false
  }
}

override viewWillLayoutSubviews() {
   super.viewWillLayoutSubviews()

   if (initialLayout == false) {
     firstLayout()
   }
}

func firstLayout() {
  // All my layout code
  initialLayout = true
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    // All my layout code
}
相关问题