2010-10-25 150 views
18

UIView有一個SizeToFit方法,它將使UIView適合所有的子視圖。有沒有類似的東西,它只會返回它計算的大小,而不會修改任何視圖的框架。SizeToFit on UIScrollView的內容大小

我在UIScrollView上有幾個子視圖,我想在scroll view的contentSize上做SizeToFit,而不是它的框架。我必須在contentSize上做,因爲我不想增加UIScrollView的「實際」大小,並且內容是動態加載和異步加載的,所以當我將子視圖添加到UIScrollView時我不能手動加載。

+0

從此開始賞金。目前,我的最佳答案是遍歷子視圖並查看其框架。我想知道是否有更好的方法。 SizeThatFits:似乎沒有幫助。 – 2010-11-22 20:47:04

+0

嘗試覆蓋sizeThatFits:執行所需的計算。 – titaniumdecoy 2010-11-29 18:51:22

+0

[夫特分機(http://stackoverflow.com/a/36504526/1634890) – 2016-04-08 16:19:26

回答

38

目前,這是最好的我:

CGRect contentRect = CGRectZero; 
for (UIView *view in self.subviews) 
    contentRect = CGRectUnion(contentRect, view.frame); 
self.contentSize = contentRect.size; 
+0

這種方法很好,但是...由於某種原因,如果手機處於橫向模式,它不適用於我。有任何想法嗎? – Reuven 2012-03-29 07:05:38

+0

該解決方案不考慮到已經存在的UIScrollView子視圖如果滾動條設置爲顯示的UIImageViews(見本SO後(http://stackoverflow.com/questions/5664281/uiscrollview-phantom-subviews ))。將這些過濾出來的一種方法是將用戶希望包含在for循環計算中的子視圖的標籤屬性設置爲相同的非零值,並使用if語句進行過濾。 – 2012-06-01 09:43:12

+1

@adamjansch或使用'isKindOfClass:'代替'標籤'。或使用:'[self.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@ 「級=%@」,[UILabel類]]];' - 不正確,因爲它使用'class'而不是'isKindOfClass:',但不夠好最使用。 – 2012-06-15 16:14:28

0

將UIView放入具有相同寬度和高度的UIScrollView,並將所有子視圖添加到IT而不是滾動視圖。然後將scrollview上的clipToBounds屬性設置爲TRUE,並在您的UIView上調用sizeToFit。您還可以將UIView背景的不透明度設置爲0,使其不可見,但仍顯示其子視圖。

+0

我只是意識到,它應該是周圍的其他方法:包封視圖應該是UIView的,而內(較大的)視圖應透明的UIScrollView。那麼它應該工作。 – thgc 2010-10-28 14:07:58

+0

你肯定,你在你的答案寫是有道理的,我有什麼,雖然你說有,但似乎有點「unproper」 – 2010-10-28 20:52:22

+0

對不起,我遲到反應......我部分用於自己的項目將上述溶液在上週工作。不幸的是,sizeToFit似乎對UIView中的UIScrollView沒有任何影響。所以我已經添加了所有子視圖後手動設置它的contentSize。這樣做甚至不需要封閉的UIView了。 – thgc 2010-11-02 15:06:11

4

如果你的函數被頻繁調用,您不希望每次在子視圖進行迭代。相反,無論何時添加子視圖,都要對當前的contentSize和新子視圖的框架進行聯合。

- (void)didAddSubview:(UIView *)subview { 
    CGRect tmp; 
    tmp.origin = CGPointZero; 
    tmp.size = self.contentSize; 
    tmp = CGRectUnion(tmp,subview.frame); 
    self.contentSize = tmp.size; 
} 
+0

在某些情況下可能是一個很好的解決方案。不幸的是,我的子視圖經常會調整大小。所以在我的情況下,這不是一個好的解決方案。 – 2010-11-29 14:03:16

+0

@WilliamJockusch如果子視圖頻繁調整大小,您可以爲'frame'或'bounds'添加一個KVO觀察者並相應地更新'contentSize'。這將變得棘手,但取決於子視圖的數量,可能是值得的。 – 2012-06-15 16:16:42

2

找到了解決辦法在這裏ScrollView ContentSize,你就能找到子視圖的大小和找到的總含量的大小,也選擇說子視圖是否水平或垂直排列。

這裏是從上面的鏈接代碼:

@interface UIScrollView(auto_size) 
- (void) adjustHeightForCurrentSubviews: (int) verticalPadding; 
- (void) adjustWidthForCurrentSubviews: (int) horizontalPadding; 
- (void) adjustWidth: (bool) changeWidth andHeight: (bool) changeHeight withHorizontalPadding: (int) horizontalPadding andVerticalPadding: (int) verticalPadding; 
@end 

@implementation UIScrollView(auto_size) 
- (void) adjustWidth: (bool) changeWidth andHeight: (bool) changeHeight withHorizontalPadding: (int) horizontalPadding andVerticalPadding: (int) verticalPadding { 
    float contentWidth = horizontalPadding; 
    float contentHeight = verticalPadding; 
    for (UIView* subview in self.subviews) { 
     [subview sizeToFit]; 
     contentWidth += subview.frame.size.width; 
     contentHeight += subview.frame.size.height; 
    } 

    contentWidth = changeWidth ? contentWidth : self.superview.frame.size.width; 
    contentHeight = changeHeight ? contentHeight : self.superview.frame.size.height; 

    NSLog(@"Adjusting ScrollView size to %fx%f, verticalPadding=%d, horizontalPadding=%d", contentWidth, contentHeight, verticalPadding, horizontalPadding); 
    self.contentSize = CGSizeMake(contentWidth, contentHeight); 
} 

- (void) adjustHeightForCurrentSubviews: (int) verticalPadding { 
    [self adjustWidth:NO andHeight:YES withHorizontalPadding:0 andVerticalPadding:verticalPadding]; 
} 

- (void) adjustWidthForCurrentSubviews: (int) horizontalPadding { 
    [self adjustWidth:YES andHeight:NO withHorizontalPadding:horizontalPadding andVerticalPadding:0]; 
} 
@end 

同時一定要看看博客頁面上的評論作爲提供替代解決方案。

-anoop

1

我已經作出一個功能設置滾動視圖的內容大小嚐試它,享受

首先寫這個函數...

-(void)setContentSizeOfScrollView:(UIScrollView*)scroll 
{ 
    CGRect rect = CGRectZero; 

    for(UIView * vv in [scroll subviews]) 
    { 
     rect = CGRectUnion(rect, vv.frame); 
    } 

    [scroll setContentSize:CGSizeMake(rect.size.width, rect.size.height)]; 
} 

再加入所有元素之後只需調用該函數並將滾動視圖作爲參數傳遞即可.....

[self setContentSizeOfScrollView:self.YourScrollView]; 

我100%肯定它會工作.........

0

在SWIFT 2.1,添加到您的視圖控制器:

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    let aggregateView = contentView.subviews.reduce(CGRect()) 
     { aggRect, view in aggRect.union(view.frame) } 

    scrollView.contentSize = aggregateView.size 

} 
-1

斯威夫特2擴展:

用法:

scrollView.contentResize
scrollView.contentWidthResize
scrollView.contentHeightResize

extension UIScrollView { 

    ///Will resize content size to fit all subviews. 
    func contentResize(){ 

     var w = CGFloat(0) 
     var h = CGFloat(0) 

     for view in self.subviews{ 

      let fw = view.frame.origin.x + view.frame.width 
      let fh = view.frame.origin.y + view.frame.height 

      w = max(fw, w) 
      h = max(fh, h) 

     } 

     contentSize = CGSize(width: w, height: h) 

    } 

    ///Will resize content width size to fit all subviews. 
    func contentWidthResize(){ 

     var w = CGFloat(0) 

     for view in self.subviews{ 

      let fw = view.frame.origin.x + view.frame.width 

      w = max(fw, w) 

     } 

     contentSize.width = w 

    } 

    ///Will resize content height size to fit all subviews. 
    func contentHeightResize(){ 

     var h = CGFloat(0) 

     for view in self.subviews{ 

      let fh = view.frame.origin.y + view.frame.height 

      h = max(fh, h) 

     } 

     contentSize.height = h 

    } 

} 
+1

'view.w'和'view.h'未定義配對。 – 2016-07-14 20:42:37

+0

@YoussefSami編輯...,請考慮刪除downvote和投票,如果你覺得有用,謝謝你的信息。 – 2016-07-14 21:58:15

1

這是Swift 3的答案。0

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    var contentRect: CGRect = CGRect.zero 
    for view in self.scrollView.subviews { 
     debugPrint("view frame \(view.frame)") 
     contentRect = contentRect.union(view.frame) 
     debugPrint("frame \(contentRect)") 
    } 
    self.scrollView.contentSize = contentRect.size 
    debugPrint("content size \(self.scrollView.contentSize)") 
} 
1

雖然William's answer是非常有用的,它並不完美,因爲滾動條也滾動視圖的子視圖的工作。原來,訣竅是在計算內容大小之前將其隱藏起來。這裏的斯威夫特3碼會是什麼樣子:

override func viewDidLayoutSubviews() { 
    scrollView.layoutSubviews() 

    // disable scrollbars so they don't interfere during resizing 
    scrollView.showsVerticalScrollIndicator = false 
    scrollView.showsHorizontalScrollIndicator = false 

    scrollView.contentSize = scrollView.subViewArea() 

    // re-enable the scrollbars 
    scrollView.showsVerticalScrollIndicator = true 
    scrollView.showsHorizontalScrollIndicator = true 
} 

您還需要在某處添加以下擴展名在您的項目:

extension UIScrollView { 
    func subViewArea() -> CGSize { 
     var rect = CGRect.zero 
     for subview in subviews { 
      rect = rect.union(subview.frame) 
     } 

     return rect.size 
    } 
} 
0

它不夠的,工會幀大小來計算內容尺寸。因爲有時候,你的子視圖需要重疊,有時你在子視圖之間有空白。你必須知道和計算子視圖的來源。

聯盟的做法給出了A和B的設計相同的內容HIGHT。但如果你知道去年最大的子視圖,就可以計算出正確的內容高度:

enter image description here

該擴展程序可以計算真正的內容高度。

extension UIScrollView { 

func adjustContentHeight(bottomPadding: Int = 0) { 

    var lastSub: CGRect = .zero 
    self.subviews.forEach({ 
     let sub = $0.frame 
     if(sub.maxY > lastSub.maxY) { 
      lastSub = sub 
     } 
    }) 

    self.contentSize.height = lastSub.maxY + CGFloat(bottomPadding) 
} 
}