2010-10-15 20 views
35

Khi tôi thêm một chế độ xem phụ vào UIView hoặc khi tôi đổi kích thước một chế độ xem phụ hiện có, tôi mong đợi [view sizeToFit][view sizeThatFits] để phản ánh thay đổi đó. Tuy nhiên, kinh nghiệm của tôi là sizeToFit không làm gì cả, và sizeThatFits trả về cùng một giá trị trước và sau khi thay đổi.Gặp sự cố khi nhận kích thước UIViewToFit để làm bất kỳ điều gì có ý nghĩa

Dự án thử nghiệm của tôi có một chế độ xem duy nhất chứa một nút. Nhấp vào nút sẽ thêm nút khác vào chế độ xem và sau đó gọi số sizeToFit trên chế độ xem có chứa. Các giới hạn của chế độ xem được bán cho bảng điều khiển trước và sau khi thêm chế độ xem phụ.

- (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]; 
} 

Và kết quả là:

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} 

tôi phải mất một cái gì đó ở đây.

Cảm ơn.

Trả lời

48

Tài liệu hướng dẫn khá rõ ràng về điều này. -sizeToFit gọi khá nhiều -sizeThatFits: (có thể với kích thước hiện tại của chế độ xem là đối số), và việc thực hiện mặc định -sizeThatFits: hầu như không có gì (nó chỉ trả về đối số của nó).

Một số lớp con UIView ghi đè -sizeThatFits: để làm điều gì đó hữu ích hơn (ví dụ: UILabel). Nếu bạn muốn có bất kỳ chức năng nào khác (chẳng hạn như thay đổi kích thước chế độ xem để phù hợp với các bản xem trước của nó), bạn nên phân lớp UIView và ghi đè -sizeThatFits:.

+1

Cảm ơn Ole. Nên đã đọc các tài liệu chặt chẽ hơn là nhìn vào đoạn mã dựa vào hành vi ghi đè trong một phân lớp cụ thể của UIView. – FishesCycle

+2

Tôi ngạc nhiên không có câu trả lời ở đây chia sẻ việc thực hiện của họ như một ghi đè như vậy. – aleclarson

0

Bạn có thể làm một số như thế sử dụng IB một mình (xcode 4.5):

  1. Bấm vào UIView
  2. trong Kích thanh tra kéo content hugging-1 (cả hai chiều ngang và dọc)
  3. kéo compression resistance đến 1000 (cho cả hai)
  4. dưới số constraints của UIView nhấp vào Width và thay đổi priority thành 250
  5. Làm tương tự cho Chiều cao
  6. Bạn có thể sử dụng 's insetUIView để kiểm soát đệm cho trái/phải/trên/dưới
0
 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; 

này đã làm việc cho tôi.

3

Nếu bạn không ghi đè UIView, bạn chỉ có thể sử dụng tiện ích.

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 
    } 

} 

Cùng mã nhưng nhanh hơn 3 lần:

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) 
    } 
} 
Các vấn đề liên quan