使用大小约束布置UIView子视图

时间:2010-03-04 08:45:36

标签: iphone cocoa-touch uikit

给定一个看起来像这样的视图层次结构:

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}}中再次计算。这很有效,但当视图更复杂时很快就会变得一团糟。

有没有办法简化这个?我无法找到其他人如何处理这个问题的好例子。

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,视图层次结构非常复杂。最后我创建了一个UIView子类,只有充当包含有用的视图的包装器。

因为我需要从层次结构的顶部调用 - (void)sizeToFit,所以我需要一种从下到上应用大小调整的方法。我通过调用 - (void)sizeToFit来做到这一点;在超级视图的子视图中 - (CGSize)sizeThatFits:(CGSize)大小;方法

然后这是递归完成的。

我如此坚持如何以正确的顺序实现这一目标,我给自己写了一张纸条,希望其他人。希望这可以提供帮助:http://jchatard.com/understanding-uiview-layout-mecanism