创建一个基于 UIView 的子视图自动调整大小的视图

Posted

技术标签:

【中文标题】创建一个基于 UIView 的子视图自动调整大小的视图【英文标题】:create a view that autoresizes based on a UIView's subview 【发布时间】:2012-07-31 01:38:23 【问题描述】:

我有一个名为 containerView 的 UIView,其中有一些 UILabel 和 UITextView,我正在通过稍后迭代它的子视图的高度并将它们相加来调整 containerView 的最终高度。是否可以自动调整此高度?我正在使用以下方式调整子视图的高度:

CGFloat desiredHeight = [object.text sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:15] constrainedToSize:CGSizeMake(self.imageView_.frameWidth , CGFLOAT_MAX) lineBreakMode:UILineBreakModeClip].height;

是否甚至可以将特定子视图的 y 原点调整为始终位于另一个子视图下方?例如,在这个 containerView 中,我有两个 UILabel,A 和 B。我希望 B 始终低于 A。到目前为止,我正在做的是在 layoutSubviews 中计算以下内容:

[B setFrameY:A.frameY + A.frameHeight];

是否可以使用自动调整大小的蒙版来实现类似的效果?我不能使用常量的原因是因为 A 的 frameHeight 是动态的,取决于文本的长度。

【问题讨论】:

【参考方案1】:

我认为对您的问题的简短回答是,不,不会根据其子视图自动调整视图大小。关于您的后一个问题(根据另一个控件调整控件的框架),您应该查看来自WWDC 2012 的各种“自动布局”视频。

当我最初回答这个问题时,我认为我可能刚刚提供了解决方案,在重新阅读您的问题后,我认为您可能已经实施了。我很抱歉。无论如何,我包括我的旧答案供您参考。

旧答案:

关于你的第一个问题,不,我认为你必须遍历你的子视图来完成你想要的。我不认为你可以用自动调整掩码做任何事情(那些被设计成另一种方式,根据他们的超级视图边界的变化调整子视图的框架)。虽然 ios 6 承诺了一些增强功能,但我认为它无法解决您的具体挑战。

不过,您显然可以很容易地以编程方式做一些事情。您可以执行以下操作:

- (void)resizeView:(UIView *)view

    CGSize maxSize = CGSizeMake(0.0, 0.0);
    CGPoint lowerRight;

    // maybe you don't want to do anything if there are no subviews

    if ([view.subviews count] == 0)
        return;

    // find the most lowerright corner that will encompass all of the subviews

    for (UIView *subview in view.subviews)
    
        // you might want to turn off autosizing on the subviews because they'll change their frames when you resize this at the end,
        // which is probably incompatible with the superview resizing that we're trying to do.

        subview.autoresizingMask = 0;

        // if you have containers within containers, you might want to do this recursively.
        // if not, just comment out the following line

        [self resizeView:subview];

        // now let's see where the lower right corner of this subview is

        lowerRight.x = subview.frame.origin.x + subview.frame.size.width;
        lowerRight.y = subview.frame.origin.y + subview.frame.size.height;

        // and adjust the maxsize accordingly, if we need to

        if (lowerRight.x > maxSize.width)
            maxSize.width = lowerRight.x;
        if (lowerRight.y > maxSize.height)
            maxSize.height = lowerRight.y;
    

    // maybe you want to add a little margin?!?

    maxSize.width += 10.0;
    maxSize.height += 10.0;

    // adjust the bounds of this view accordingly

    CGRect bounds = view.bounds;
    bounds.size = maxSize;
    view.bounds = bounds;

只需在您可能想要根据其子视图调整大小的任何“容器”视图上调用它(最好不要将其与适当的视图控制器包含混淆,这是一种不同的野兽)。请注意,我只是调整大小(假设您也不想移动子视图或视图的origin,如果您愿意,您可以轻松地做到这一点)。我也让这个递归进行,但也许你不想这样做。您的来电。

关于第二个问题,将标签 B 移动到标签 A 下方非常简单:

CGRect frame = b.frame;
frame.origin.y = a.frame.origin.y + a.frame.size.height;
b.frame = frame;

【讨论】:

以上是关于创建一个基于 UIView 的子视图自动调整大小的视图的主要内容,如果未能解决你的问题,请参考以下文章

调整旋转 UIView 的子视图大小

使用动态大小的子视图调整 UIView 子类的大小

基于多行 UILabel 自动调整 UIView 的大小

根据子视图大小调整 XIB 中的 UIView 大小

iOS UIView 不调整子视图的大小?

使用自动布局调整 UIView 大小并更新内容