ios 无法让 UIView sizeToFit 做任何有意义的事情

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3946665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:55:35  来源:igfitidea点击:

Having trouble getting UIView sizeToFit to do anything meaningful

iphoneiosuiviewresizeuibutton

提问by FishesCycle

When I add a subview to a UIView, or when I resize an existing subview, I would expect [view sizeToFit]and [view sizeThatFits]to reflect that change. However, my experience is that sizeToFitdoes nothing, and sizeThatFitsreturns the same value before and after the change.

当我向 a 添加子视图UIView时,或者当我调整现有子视图的大小时,我会期望[view sizeToFit][view sizeThatFits]反映该更改。但是,我的经验是sizeToFit什么都不做,并且sizeThatFits在更改前后返回相同的值。

My test project has a single view that contains a single button. Clicking the button adds another button to the view and then calls sizeToFiton the containing view. The bounds of the view are dumped to the console before and after adding the subview.

我的测试项目有一个包含单个按钮的视图。单击该按钮将另一个按钮添加到视图,然后调用sizeToFit包含视图。在添加子视图之前和之后,视图的边界被转储到控制台。

- (void) logSizes {
 NSLog(@"theView.bounds: %@", NSStringFromCGRect(theView.bounds));
 NSLog(@"theView.sizeThatFits: %@", NSStringFromCGSize([theView sizeThatFits:CGSizeZero])); 
}

- (void) buttonTouched { 
 [self logSizes];
 UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
 btn.frame = CGRectMake(10.0f, 100.0f, 400.0f, 600.0f);
 [theView addSubview:btn];
 [theView sizeToFit];
 [self performSelector:@selector(logSizes) withObject:nil afterDelay:1.0];
}

And the output is:

输出是:

2010-10-15 15:40:42.359 SizeToFit[14953:207] theView.bounds: {{0, 0}, {322, 240}}
2010-10-15 15:40:42.387 SizeToFit[14953:207] theView.sizeThatFits: {322, 240}
2010-10-15 15:40:43.389 SizeToFit[14953:207] theView.bounds: {{0, 0}, {322, 240}}
2010-10-15 15:40:43.391 SizeToFit[14953:207] theView.sizeThatFits: {322, 240}

I must be missing something here.

我一定在这里遗漏了一些东西。

Thanks.

谢谢。

回答by Ole Begemann

The documentation is pretty clear on this. -sizeToFitpretty much calls -sizeThatFits:(probably with the view's current size as the argument), and the default implementation of -sizeThatFits:does almost nothing (it just returns its argument).

文档对此非常清楚。-sizeToFit几乎所有的调用-sizeThatFits:(可能以视图的当前大小作为参数),而 的默认实现-sizeThatFits:几乎什么都不做(它只是返回它的参数)。

Some UIView subclasses override -sizeThatFits:to do something more useful (e.g. UILabel). If you want any other functionality (such as resizing a view to fit its subviews), you should subclass UIView and override -sizeThatFits:.

一些 UIView 子类重写-sizeThatFits:以做一些更有用的事情(例如 UILabel)。如果您想要任何其他功能(例如调整视图大小以适应其子视图),您应该继承 UIView 并覆盖-sizeThatFits:

回答by Dmytro Shvetsov

If you won't override UIView, u can just use extension.

如果你不覆盖 UIView,你可以只使用扩展。

Swift:

迅速:

extension UIView {

    func sizeToFitCustom () {
        var size = CGSize(width: 0, height: 0)
        for view in self.subviews {
            let frame = view.frame
            let newW = frame.origin.x + frame.width
            let newH = frame.origin.y + frame.height
            if newW > size.width {
                size.width = newW
            }
            if newH > size.height {
                size.height = newH
            }
        }
        self.frame.size = size
    }

}

The same code but 3 times faster:

相同的代码,但速度提高了 3 倍:

extension UIView {
    final func sizeToFitCustom() {
        var w: CGFloat = 0,
            h: CGFloat = 0
        for view in subviews {
            if view.frame.origin.x + view.frame.width > w { w = view.frame.origin.x + view.frame.width }
            if view.frame.origin.y + view.frame.height > h { h = view.frame.origin.y + view.frame.height }
        }
        frame.size = CGSize(width: w, height: h)
    }
}

回答by marmor

You can do some like that using IB alone (xcode 4.5):

你可以单独使用 IB (xcode 4.5) 做一些类似的事情:

  1. Click on the UIView
  2. in the Size inspector drag content huggingto 1 (both horizontal and vertical)
  3. drag compression resistanceto 1000 (for both)
  4. under the UIView's constraintsclick on Widthand change priorityto 250
  5. Do the same for Height
  6. You can use the UIView's insetto control padding for left/right/top/bottom
  1. 点击 UIView
  2. 在大小检查器中拖动content hugging到 1(水平和垂直)
  3. 拖动compression resistance到 1000(对于两者)
  4. 在 UIView 下constraints点击Width并更改priority为 250
  5. 对高度做同样的事情
  6. 您可以使用UIView'sinset来控制左/右/上/下的填充

回答by shaunlim

        self.errorMessageLabel.text = someNewMessage;

    // We don't know how long the given error message might be, so let's resize the label + containing view accordingly
    CGFloat heightBeforeResize = self.errorMessageLabel.frame.size.height;

    [self.errorMessageLabel sizeToFit];

    CGFloat differenceInHeightAfterResize = self.errorMessageLabel.frame.size.height - heightBeforeResize;

    self.errorViewHeightContstraint.constant = kErrorViewHeightConstraintConstant + differenceInHeightAfterResize;

This worked for me.

这对我有用。