Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having trouble getting UIView sizeToFit to do anything meaningful

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 sizeToFit does nothing, and sizeThatFits returns the same value before and after the change.

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

- (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.

like image 806
FishesCycle Avatar asked Oct 15 '10 22:10

FishesCycle


People also ask

What does sizeToFit do?

sizeToFit()Resizes the receiver's frame so that it's the minimum size needed to contain its cell.

What is a UIView?

The UIView class is a concrete class that you can instantiate and use to display a fixed background color. You can also subclass it to draw more sophisticated content.

What is swift sizeToFit?

sizeToFit()Resizes and moves the receiver view so it just encloses its subviews.


2 Answers

The documentation is pretty clear on this. -sizeToFit pretty 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).

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:.

like image 124
Ole Begemann Avatar answered Sep 19 '22 14:09

Ole Begemann


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

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:

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)     } } 
like image 22
Dmytro Shvetsov Avatar answered Sep 20 '22 14:09

Dmytro Shvetsov