自动布局导致无限的layoutSubviews循环

4

我对此感到困惑,当我在子视图上使用自动布局时,layoutSubview方法会无限循环。

我所做的只是:

- (id)init
{
    self = [super init];
    if(self)
    {
        self.backgroundColor = [UIColor grayColor];
        _imageView = [[UIImageView alloc] init];
        _imageView.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:_imageView];

        [self applyConstraints];

    }
    return self;
}

-(void)applyConstraints
{
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_imageView]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageView)]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_imageView]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageView)]];
}

这会导致layoutSubviews方法进入一个无限循环。实际上,即使没有调用applyConstraints方法,循环也会发生,唯一阻止它发生的方式是将"translatesAutoresizingMaskIntoConstraints"设置为YES。

有人遇到/解决过这个问题吗?

更新: 仅澄清一下,这是一个UIView子类,用于视图控制器中。该视图本身不使用自动布局,而是在初始化后以传统的方式设置其frame。


我猜你在别的地方做错了,因为我已经复制粘贴了你的代码并注释了“translatesAutoresizingMaskIntoConstraints”,但它仍然可以正常工作,layoutSubview没有被无限调用。 - Prasad Devadiga
目前我使用框架进行了一些工作,等我有空的时候会尝试在一个空项目中重新制作它,我会在这样做时更新问题。同时,您知道什么可能导致无限循环吗?我似乎无法在任何地方找到关于无限layoutSubviews循环主题的任何内容。 - Alvin
你是对的,问题出在其他地方。其中一个父视图在其layoutSubviews方法中移除并重新添加了其子视图。我不确定为什么会这样做,因为这是完全没有必要的... - Alvin
3个回答

19
这可能会对你有帮助。

当视图的frame发生改变时,将调用layoutSubviews方法。

  • 当视图从父视图中移除时,它将在父视图上被调用。
  • 在UIScrollView中,在滚动期间。
  • 当将视图添加到superView中时。
  • 在方向更改期间。

7
循环是由其中一个父视图引起的,它删除其子视图,设置它们(可能是新的)的框架,然后重新添加它们。由于这段代码是绝对不必要的,我将其删除,解决了问题。

很好,你找出了问题。 :) - Prasad Devadiga
实际上,更改框架并不是问题,但创建新的UIVIEW并将它们添加到视图控制器的视图中会再次调用didLayoutSubviews。 而且你是对的,这段代码是不必要的,没有必要删除和重新创建,只需重复使用即可。 - Vassily

1
如果有歧义,比如两个未确定的大于/小于方程式,那么这也会出现。您应该将其中一个限制条件改为直接相等。同时,尝试通过追踪来检测这种歧义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接