给定一个看起来像这样的视图层次结构:
ContainerView
UIScrollView
ModuleView
ModuleView
ModuleView
...
我希望ContainerView
以任意方式(列表,网格等)放置ModuleViews
。为此,我将实现-[ContainerView layoutSubviews]
,它将遍历ModuleViews
,在每个-[ModuleView sizeToFit]
上调用-[ModuleView sizeThatFits:]
,然后根据所需的布局将它们相对于彼此放置。
我的问题是如何最好地实施-[ModuleView layoutSubviews]
和ModuleViews
以最大限度地减少重复,并允许ModuleView
更改大小,同时正确维护布局。
在最简单的情况下,UIView
是一个UILabel
,其中包含多行@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
中计算一次,在{{1}}中再次计算。这很有效,但当视图更复杂时很快就会变得一团糟。
有没有办法简化这个?我无法找到其他人如何处理这个问题的好例子。
答案 0 :(得分:1)
我遇到了同样的问题,视图层次结构非常复杂。最后我创建了一个UIView子类,只有充当包含有用的视图的包装器。
因为我需要从层次结构的顶部调用 - (void)sizeToFit,所以我需要一种从下到上应用大小调整的方法。我通过调用 - (void)sizeToFit来做到这一点;在超级视图的子视图中 - (CGSize)sizeThatFits:(CGSize)大小;方法
然后这是递归完成的。
我如此坚持如何以正确的顺序实现这一目标,我给自己写了一张纸条,希望其他人。希望这可以提供帮助:http://jchatard.com/understanding-uiview-layout-mecanism