2012-05-09 33 views
19

Tôi có câu hỏi về UIScrollview.Cách đặt kích thước nội dung của UIScrollView động

Câu chuyện là tôi có UIView tên là ChartsView mà tôi tự vẽ lại bằng phương pháp ghi đè drawRect(). Nội dung bản vẽ được tạo động. Vì vậy, tôi không biết kích thước của nó cho đến khi thời gian chạy. Câu hỏi đặt ra là làm cách nào/ở đâu tôi có thể đặt kích thước nội dung của chế độ xem siêu (scrollView) động? Bất kỳ ý tưởng nào về điều đó?

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

    } 

Trả lời

1

thử

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

không may mắn. Tôi cố gắng để tìm một workaround, thiết lập kích thước nội dung của scrollview trong bảng xếp hạng xem khi vẽ done.Now câu hỏi là loại api tôi có thể sử dụng để nhận được kích thước actuall của chartsView ((UIScrollView *) [self superview]). ContentSize = CGSizeMake (320, 480); –

54

Thêm một cách dễ dàng này

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

mẹo hay. Nó có thể được sử dụng cho bất kỳ 'UIScrollView' nào. 1 cho điều đó. –

+0

Tôi chỉ muốn thêm một điều. Một số bạn có thể muốn đặt mã này trong viwDidAppear: vì UIView của bạn có thể được vẽ trước khi viewDidAppear nhưng sau khi viewDidLoad được gọi; Điều này sẽ cho phép bạn có quyền truy cập vào chiều cao mới nhất của chế độ xem. – mvb

+10

lastObject trả về đối tượng cuối cùng được lập chỉ mục trong mảng subviews, chứ không phải subview dưới cùng nhất trên màn hình. trên thực tế, lastObject không liên quan gì đến vị trí của khung nhìn và sử dụng nó sai. – AmitP

5

nhanh chóng (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 

} 

Trên ofcourse là khi bạn chỉ có một sửa chữa số lượng lượt xem trên cuộn của bạn. Phương pháp IOS Rocks có sẵn nhưng không tốt cho tôi, tạo thêm không gian sau đó tôi cần.

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

Nhờ IOS Rocks và CularBytes dẫn đầu về điều này. Tôi đã tìm thấy hai vấn đề (đối với tôi) với các giải pháp trên:

  1. Tôi luôn luôn có một thùng chứa UIView là đứa con duy nhất của UIScrollView của tôi, vì vậy tôi phải cập nhật cách tôi tra cứu lần cuối trong đứa trẻ đó UIView (xem dưới đây)
  2. tôi offset'ing nội dung của tôi trong UIScrollView và như vậy cần thiết để tính toán vị trí tuyệt đối về điều đó UIView cuối cùng (vì vậy, liên quan đến cửa sổ không phải là cái nhìn mẹ)

Ngoài ra tôi đang sử dụng autolayout để ghim các mặt của UIScrollView, vì vậy tôi không cần phải lo lắng về chiều rộng (như là CularBytes).

Đây là những gì tôi đã đưa ra và các công trình (trong Swift 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 
} 

Tôi gọi đây là trong phương pháp viewDidAppear() tôi.

1

Hãy thử điều này -

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

Nó không phải là 100% đảm bảo rằng đối tượng cuối cùng trong mảng scrollView.subviews sẽ trả lại đối tượng y nguồn gốc cao nhất theo quan điểm di chuyển của bạn. Mảng subviews được sắp xếp bởi Z-Index (tức là đối tượng cuối cùng trong mảng subviews sẽ là đối tượng được xếp chồng lên nhau cao nhất và sẽ là subview nhiều nhất trong các subviews của xem cuộn. Thay vào đó, sử dụng chức năng sắp xếp cơ bản là chính xác hơn để lặp qua các bản xem trước và lấy đối tượng có nguồn gốc y cao nhất.

Đây là một chức năng cơ bản trong nhanh chóng 3 mà có thể làm như vậy:

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

sử dụng (trong viewDidLayoutSubviews hoặc bất cứ khi nào cập nhật kích thước nội dung của bạn):

scrollView.contentSize = calculateContentSize(scrollView: scrollView) 

CẬP NHẬT SWIFT 4

Dưới đây là một phiên bản bảo thủ hơn trong swift 4

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

Cách sử dụng:

myScrollView.updateContentView() 
0

Đây là một phần mở rộng được viết trên Swift 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 
    } 
} 
vẫn
Các vấn đề liên quan