在继承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
中完成?
答案 0 :(得分:15)
您的init应该使用所需的数据创建所有对象。你在init中传递给它们的任何帧理想地应该是它们的起始位置。
然后,在layoutSubviews:中,您可以更改所有元素的帧以将它们放置在应该去的位置。在layoutSubviews中不应该进行分配或初始化,只需更改其位置,大小等...
答案 1 :(得分:4)
如果你的自动调整功能与autoresizingFlags或autolayout完美配合,你可以只使用init来设置整个视图。
但总的来说,你应该在layoutSubviews中进行布局,因为这将在视图框架的每次更改时调用,而在其他情况下,需要再次布局。有时你只是不知道init中视图的最终帧,所以你需要像上面提到的那样灵活,或者使用layoutSubviews,因为你在设置了最终大小之后进行了布局。
如WDUK所述,所有初始化代码/对象创建都应该在init方法中或任何地方,但是layoutSubviews中的不是。