2012-05-09 52 views
19

我有問題關於UIScrollview如何動態設置UIScrollView的內容大小

故事是我有一個名爲ChartsView的UIView,我用覆蓋方法drawRect()自己重新繪製它。繪圖的內容是動態生成的。所以我直到運行時才知道它的大小。問題是如何/我在哪裏可以動態設置其超級視圖(scrollView)內容大小?對此有何想法?

- (void)viewDidLoad 
    { 
     [super viewDidLoad]; 

// not this way. it's fixed size..... 
     ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; 

     self.scrollView.contentSize = chartsView.frame.size; 

     [self.scrollView addSubview:chartsView]; 

    } 

回答

1

試試這個

- (void)viewDidLoad 
     { 
      [super viewDidLoad]; 

    // not this way. it's fixed size..... 
      ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; 

      self.scrollView.contentSize = chartsView.frame.size; 
      [self.scrollView setNeedsDisplay]; 
      [self.scrollView addSubview:chartsView]; 

    } 
+0

仍然沒有運氣的延伸。我嘗試找到一種解決方法,在繪製完成後在Charts視圖中設置scrollview的內容大小。現在的問題是我可以使用什麼類型的API來獲取圖表的實際大小。((UIScrollView *)[self superview])。contentSize = CGSizeMake(320,480); –

54

一個更簡單的方法

- (void)viewDidLoad 
{ 
    float sizeOfContent = 0; 
    UIView *lLast = [scrollView.subviews lastObject]; 
    NSInteger wd = lLast.frame.origin.y; 
    NSInteger ht = lLast.frame.size.height; 

    sizeOfContent = wd+ht; 

    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, sizeOfContent); 
} 
+0

不錯的把戲。它可以用於任何'UIScrollView'。 +1。 –

+0

我只想補充一件事。你們中的一些人可能喜歡把這段代碼放到viwDidAppear中:因爲你的UIView可能會在viewDidAppear之前被繪製,但是在viewDidLoad被調用之後;這將使您能夠訪問視圖的最新高度。 – mvb

+10

lastObject返回子視圖數組中索引的最後一個對象,而不是屏幕上最底部的子視圖。實際上,lastObject與視圖的位置無關,並且使用它是錯誤的。 – AmitP

5

迅速(2.0)

@IBOutlet weak var btnLatestButton: UIButton! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let height = btnLatestButton.frame.size.height 
    let pos = btnLatestButton.frame.origin.y 
    let sizeOfContent = height + pos + 10 
    scrollview.contentSize.height = sizeOfContent 

} 

以上ofcourse是當你只是在修復在您的滾動視圖上顯示的視圖數量。 IOS岩石方法可用,但對我不好,創造了更多的空間,然後我需要。

let lastView : UIView! = scrollview.subviews.last 
    let height = lastView.frame.size.height 
    let pos = lastView.frame.origin.y 
    let sizeOfContent = height + pos + 10 
    scrollview.contentSize.height = sizeOfContent 
3

感謝IOS岩石和CularBytes在這方面的線索。我發現了兩個問題(對我來說)上述解決方案:

  1. 我一直有一個容器的UIView作爲我的UIScrollView唯一的孩子,所以我不得不更新我仰望最後查看該孩子的UIView的方式(見下文)
  2. 我offset'ing我在的UIScrollView和內容,來計算最後的UIView(因此,相對於窗口而不是父視圖)

我也絕對位置所需我使用自動佈局來固定UIScrollView的邊,所以我不需要擔心寬度(因爲是CularBytes)。

這就是我想出了與工作(在雨燕3.0):

func setScrollViewContentSize() { 

    var height: CGFloat 
    let lastView = self.myScrollView.subviews[0].subviews.last! 
    print(lastView.debugDescription) // should be what you expect 

    let lastViewYPos = lastView.convert(lastView.frame.origin, to: nil).y // this is absolute positioning, not relative 
    let lastViewHeight = lastView.frame.size.height 

    // sanity check on these 
    print(lastViewYPos) 
    print(lastViewHeight) 

    height = lastViewYPos + lastViewHeight 

    print("setting scroll height: \(height)") 

    myScrollView.contentSize.height = height 
} 

我在viewDidAppear()方法調用它。

1

試試這個 -

- (void)viewDidLoad 
    { 
     [super viewDidLoad]; 

// not this way. it's fixed size..... 
     ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; 

     //self.scrollView.contentSize = chartsView.frame.size; 
     [self.scrollView setContentSize:CGSizeMake(chartsView.frame.size.width, chartsView.frame.size.height)]; 
     [self.scrollView addSubview:chartsView]; 

    } 
1

它不是100%的保證,在scrollView.subviews數組的最後一個對象會在你的滾動視圖返回最高的y源對象。子視圖數組由Z-Index排列(即子視圖數組中的最後一個對象將是堆疊得最高的對象,並且將成爲滾動視圖子視圖中最頂層的子視圖,相反,使用基本排序功能會更準確遍歷子視圖並獲取y最高的對象。

這裏是SWIFT 3基本功能是可以這樣做的:

func calculateContentSize(scrollView: UIScrollView) -> CGSize { 
    var topPoint = CGFloat() 
    var height = CGFloat() 

    for subview in scrollView.subviews { 
     if subview.frame.origin.y > topPoint { 
      topPoint = subview.frame.origin.y 
      height = subview.frame.size.height 
     } 
    } 
    return CGSize(width: scrollView.frame.size.width, height: height + topPoint) 
} 

使用(在viewDidLayoutSubviews或當你的內容大小更新):

scrollView.contentSize = calculateContentSize(scrollView: scrollView) 

UPDATE SWIFT 4

以下是swift中的更簡潔的版本4

extension UIScrollView { 
    func updateContentView() { 
     contentSize.height = subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? contentSize.height 
    } 
} 

用法:

myScrollView.updateContentView() 
0

這是寫在斯威夫特3

extension UIScrollView { 
    func updateContentViewSize() { 
     var newHeight: CGFloat = 0 
     for view in subviews { 
      let ref = view.frame.origin.y + view.frame.height 
      if ref > newHeight { 
       newHeight = ref 
      } 
     } 
     let oldSize = contentSize 
     let newSize = CGSize(width: oldSize.width, height: newHeight + 100) 
     contentSize = newSize 
    } 
}