给定一个看起来像这样的 View 层次结构:
ContainerView
UIScrollView
ModuleView
ModuleView
ModuleView
...
我希望ContainerView
以某种任意方式(列表、网格等)放置ModuleViews
。为此,我将实现 -[ContainerView layoutSubviews]
,它将迭代 ModuleViews
,对每个 View 调用 -[ModuleView sizeToFit]
,然后根据所需的布局将它们相对放置。
我的问题是如何实现 -[ModuleView sizeThatFits:]
和 -[ModuleView layoutSubviews]
的最佳方式,以最大限度地减少重复并允许 ModuleViews
更改大小,同时保持正确的布局。
采用最简单的情况,其中 ModuleView
是一个 UIView
,带有多行 UILabel
subview ,并在两侧进行填充。它可能看起来像这样:
@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
如您所见, subview 的大小在 sizeThatFits:
中计算一次,并在 layoutSubviews
中再次计算。这可行,但当 View 更复杂时很快就会变得一团糟。
有没有办法简化这个过程?我还没有找到其他人如何解决这个问题的好例子。
最佳答案
我遇到了同样的问题, View 层次结构非常复杂。我最终创建了一个 UIView 子类,它仅充当包含我的有用 View 的包装器。
因为我需要从层次结构的顶部调用 -(void)sizeToFit,所以我需要一种从下到上应用此大小调整的方法。我通过调用 -(void)sizeToFit; 做到了这一点在父 View 的 subview 上 -(CGSize)sizeThatFits:(CGSize)size;方法。
然后这是递归完成的。
我对如何以正确的顺序实现这一目标非常困惑,所以我给自己写了一张便条,希望也给其他人。希望这可以帮助:http://jchatard.com/understanding-uiview-layout-mecanism
关于iphone - 布局具有大小约束的 UIView subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2377873/