2012-05-09 4 views
19

UIScrollview에 대한 질문이 있습니다.동적으로 UIScrollView의 콘텐츠 크기를 설정하는 방법

이야기는 내가 ChartsView라는 이름으로 재정의 방법 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

행운 스위프트 3에 기록 확장입니다. 해결 방법을 찾으려고, 차트보기에서 슬라이드 뷰의 콘텐츠 크기를 설정하려고 할 때. 이제는 차트의 실제 크기를 가져 오는 데 사용할 수있는 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

한 가지만 추가하고 싶습니다. VIEWDidAppear에이 코드를 넣으시겠습니까? viewDidAppear 전에 UI 뷰가 그려지기 때문에 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 

} 

입니다 시도 스크롤 뷰의 조회수입니다. IOS Rocks 방법을 사용할 수 있지만 나에게 좋지 않았습니다. 필요한 공간이 더 많았습니다.

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의 Rocks와 CularBytes가이 문제를 해결했습니다. 나는 위의 솔루션 (나를 위해) 두 가지 문제를 발견

난 항상 내있는 UIScrollView의 유일한 자식으로 컨테이너 UIView의, 그래서 내가 그 아이의 UIView의 마지막보기를 보는 방식을 업데이트했다
    1. 나는있는 UIScrollView와 같은 내 콘텐츠를 offset'ing하고
    2. (아래 참조) 등 또한

    나는 (창없는 부모보기로 그래서 상대) 마지막으로 UIView의 절대 위치를 계산하는 데 필요한 autolayout을 사용하여 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

    그것은 scrollView.subviews 배열의 마지막 개체가 스크롤 뷰에서 가장 높은 Y-원점 객체를 반환 보장 100 %가 아니다. 서브 뷰 배열은 Z- 인덱스에 의해 배열됩니다 (즉, 서브 뷰 배열의 마지막 객체는 가장 많이 쌓인 객체이며 스크롤 뷰의 서브 뷰에서 최상위 서브 뷰가 될 것입니다.) 대신 기본 정렬 함수를 사용하는 것이 더 정확합니다 하위 뷰를 반복하고 가장 높은 y- 원점을 가진 객체를 가져옵니다.(콘텐츠 크기 업데이트 viewDidLayoutSubviews 또는 때마다)

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

    사용법 :

    scrollView.contentSize = calculateContentSize(scrollView: scrollView) 
    

    업데이트 SWIFT 4

    다음

    는 기본이 그렇게 할 수있는 빠른 3의 기능입니다

    여기가 더 신속한 버전입니다.

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

    사용법 :

    myScrollView.updateContentView() 
    
    0

    이 여전히

    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 
        } 
    } 
    
    관련 문제