UIView:layoutSubviews 与 initWithFrame

Posted

技术标签:

【中文标题】UIView:layoutSubviews 与 initWithFrame【英文标题】:UIView: layoutSubviews vs initWithFrame 【发布时间】:2012-11-01 12:38:06 【问题描述】:

当子类化UIView 时,我通常将我所有的初始化和布局代码放在它的init 方法中。但有人告诉我布局代码应该通过覆盖layoutSuviews 来完成。 SO上有一个post,它解释了何时每个方法被调用,但我想知道如何在实践中使用它们。

我目前将所有代码都放在init 方法中,如下所示:

MyLongView.m

- (id)initWithHorizontalPlates:(int)theNumberOfPlates

    self = [super initWithFrame:CGRectMake(0, 0, 768, 1024)];

    if (self) 
        // Initialization code
        _numberOfPlates = theNumberOfPlates;

        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
        [scrollView setContentSize:CGSizeMake(self.bounds.size.width* _numberOfPlates, self.bounds.size.height)];
        [self addSubview:scrollView];

        for(int i = 0; i < _numberOfPlates; i++)
            UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"a1greatnorth_normal_%d.jpg", i+1]];
            UIImageView *plateImage = [[UIImageView alloc] initWithImage:img];
            [scrollView addSubview:plateImage];
            plateImage.center = CGPointMake((plateImage.bounds.size.width/2) + plateImage.bounds.size.width*i, plateImage.bounds.size.height/2);
        

    
    return self;

这是通常的任务:设置视图的框架、初始化 ivar、设置滚动视图、初始化 UIImages、将它们放入 UIImageViews、布局它们。

我的问题是:哪些应该在init 中完成,哪些应该在layoutSubviews 中完成?

【问题讨论】:

【参考方案1】:

您的 init 应该使用所需的数据创建所有对象。您在 init 中传递给它们的任何帧都应该是它们的起始位置。

然后,在 layoutSubviews: 中,您更改所有元素的框架以将它们放置在它们应该去的地方。不应在 layoutSubviews: 中进行分配或初始化,仅更改其位置、大小等...

【讨论】:

【参考方案2】:

如果您使用 autoresizingFlags 或 autolayout 完美调整大小,您可以只使用 init 来设置整个视图。

但一般来说,您应该在 layoutSubviews 中进行布局,因为这将在视图框架的每次更改以及其他需要再次布局的情况下调用。有时您只是不知道 init 中视图的最终帧,因此您需要如上所述灵活,或者使用 layoutSubviews,因为您在设置最终尺寸后在那里进行布局。

正如 WDUK 所说,所有初始化代码/对象创建都应该在您的 init 方法中或任何地方,但在 layoutSubviews 中。

【讨论】:

我会把它往下推。在 viewDidLoad 而不是 init 中创建您的子视图对象。视图是延迟加载的,如果不创建超级视图,就没有理由创建子视图。 我们在这里讨论的是视图,而不是 ViewController。

以上是关于UIView:layoutSubviews 与 initWithFrame的主要内容,如果未能解决你的问题,请参考以下文章

UIView的layoutSubviews和drawRect方法何时调用

UIView的layoutSubviews和drawRect方法何时调用

UIView的layoutSubviews和drawRect方法何时调用

UIView的layoutSubviews和drawRect方法何时调用

UIView layoutSubviews 通知

iOS UIView:setNeedLayout、setNeedDisplay、layoutSubViews 和 layoutIfNeeded