【发布时间】:2010-03-04 08:45:36
【问题描述】:
给定一个看起来像这样的视图层次结构:
ContainerView
UIScrollView
ModuleView
ModuleView
ModuleView
...
我希望ContainerView 以任意方式(列表、网格等)放置ModuleViews。为此,我将实现-[ContainerView layoutSubviews],它会遍历ModuleViews,在每一个上调用-[ModuleView sizeToFit],然后根据所需的布局将它们相对定位。
我的问题是与实现-[ModuleView sizeThatFits:] 和-[ModuleView layoutSubviews] 的最佳方式有关,以尽量减少重复并允许ModuleViews 在正确保持布局的同时更改大小。
以最简单的情况为例,ModuleView 是带有多行 UILabel 子视图的 UIView,并且两边都有填充。它可能看起来像这样:
@implementation ModuleView
- (CGSize)sizeThatFits:(CGSize)size {
CGFloat padding = 10.0f;
CGSize labelMaxSize = CGSizeMake(superview.size.width - (2 * padding), CGFLOAT_MAX);
CGSize labelSize = [self.label.text sizeWithFont:self.label.font constrainedToSize:labelMaxSize lineBreakMode:self.label.lineBreakMode];
return CGSizeMake(superview.width, labelSize.height + (2 * padding));
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat padding = 10.0f;
CGSize labelMaxSize = CGSizeMake(self.size.width - (2 * padding), CGFLOAT_MAX);
CGSize labelSize = [self.label.text sizeWithFont:self.label.font constrainedToSize:labelMaxSize lineBreakMode:self.label.lineBreakMode];
self.label.frame = CGRectMake(padding, padding, labelSize.width, labelSize.height);
CGRect frame = self.frame;
frame.size.height = self.label.frame.size.height + (2 * padding);
self.frame = frame;
}
@end
如您所见,子视图的大小在sizeThatFits: 中计算一次,在layoutSubviews 中再次计算。这可行,但当视图更复杂时,很快就会变得一团糟。
有没有办法简化这个?我找不到其他人如何解决这个问题的好例子。
【问题讨论】:
-
嗨,Nathan,有针对这种情况的新解决方案吗?
标签: iphone cocoa-touch uikit