7

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

我目前将所有代码都放在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

4

2 回答 2

16

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

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

于 2012-11-01T12:49:17.213 回答
4

如果您的自动调整大小仅与 autoresizingFlags 或 autolayout 完美配合,您可以只使用 init 来设置整个视图。

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

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

于 2012-11-01T12:56:16.633 回答