无法获得UIView sizeToFit做任何有意义的事情

当我添加一个子视图到一个UIView ,或者当我调整现有的子视图,我期望[view sizeToFit][view sizeThatFits]来反映这种变化。 但是,我的经验是, sizeToFit什么都不做, sizeThatFits在更改前后返回相同的值。

我的testing项目有一个包含一个button的单一视图。 单击该button将向视图添加另一个button,然后在包含的视图上调用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]; } 

输出是:

 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} 

我必须在这里错过一些东西。

谢谢。

这个文件很清楚。 -sizeToFit几乎可以调用-sizeThatFits:可能以视图的当前大小为参数),而-sizeThatFits:的默认实现几乎不做任何事情(只是返回它的参数)。

一些UIView子类覆盖-sizeThatFits:做一些更有用的事情(例如UILabel)。 如果你想要任何其他的function(比如调整视图的大小来适应它的子视图),你应该-sizeThatFits: UIView并覆盖-sizeThatFits:

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

迅速:

 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 } } 

相同的代码,但速度快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) } } 

你可以使用IB(xcode 4.5)来做一些这样的事情:

  1. 点击UIView
  2. 在“大小”检查器中,将content hugging拖到1(水平和垂直)
  3. compression resistance降至1000(两者)
  4. 在UIView的constraints点击Width并将priority改为250
  5. 为高度做同样的事情
  6. 你可以使用UIViewinset来控制左/右/上/下的填充
  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; 

这对我有效。