2012-06-10 30 views
25

Tôi đang cố gắng tạo lại hoạt ảnh mượt mà của một cuộn với tính năng phân trang được bật khi bạn thực sự cuộn đến trang tiếp theo. Có vẻ như là UIViewAnimationCurveEaseInOut, nhưng tôi cần có nút "trang tiếp theo" và di chuyển theo chương trình.UIScrollview setContentBật với hoạt ảnh không tuyến tính?

Đây là mã của tôi:

-(void) scrollToPage:(int)page 
{ 
    UIScrollView *scrollView = contentView; 
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, scrollView.contentOffset.y); 
    [scrollView setContentOffset:offset animated: YES];  
    [self pageControlUpdate]; 
} 

-(void) scrollToNextPage 
{ 
    [self scrollToPage:(pageControl.currentPage + 1)]; 
} 

tôi không thể quản lý để tái tạo sự mượt mà của UIViewAnimationCurveEaseInOut, hoặc với setContentOffset, hoặc với scrollRectToVisible ... nó đi đến trang tiếp theo với một hình ảnh động tuyến tính xấu xí

tôi thậm chí đã cố gắng để animate nó bằng tay:

[UIView animateWithDuration:.5 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{ 
    scrollView.contentOffset = offset; 
} completion:^(BOOL finished) { } ]; 

Tôi đang ở đâu?

+0

Tôi đã tìm thấy điều này: http://developer.apple.com/library/ios/#DOCUMENTATION/WindowsViews/Conceptual/UIScrollView_pg/ScrollingViewContent/ScrollingViewContent.html xác nhận những gì tôi đã thấy: 'Phương thức setContentOffset: animated: cuộn nội dung để bù đắp nội dung được chỉ định. Nếu tham số động là CÓ, cuộn sẽ hoạt hình từ vị trí hiện tại đến vị trí đã chỉ định với tốc độ không đổi.' – Diwann

+0

arg. Noone có thể có bất kỳ đầu mối? – Diwann

+0

Vâng, nếu 'UIViewAnimationCurveEaseInOut' không hoạt động, đó có thể là đường cong hoạt hình khác. Rất có thể Apple sử dụng đường cong tùy chỉnh cho hoạt ảnh này. Sử dụng 'CAPropertyAnimation', bạn có thể định nghĩa đường cong tùy chỉnh của riêng mình dưới dạng' CAMediaTimingFunction'. Nó có thể là giá trị chơi xung quanh với các điểm kiểm soát khác nhau. –

Trả lời

21

Mỗi lần bạn thực hiện hình ảnh động riêng của bạn, bạn phải vượt qua NO như animated: tham số:

- (void)scrollToPage:(int)page 
{ 
    UIScrollView *scrollView = contentView; 
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, 
           scrollView.contentOffset.y); 

    [UIView animateWithDuration:.5 
          delay:0 
         options:UIViewAnimationCurveEaseInOut 
        animations:^{ 
         [scrollView setContentOffset:offset animated:NO]; 
        } completion:nil]; 

    [self pageControlUpdate]; 
} 
+0

và btw. thời gian hoạt ảnh cố định sẽ có vẻ lạ trong một số trường hợp. ví dụ. bạn chỉ cuộn 2 dòng nó cũng sẽ mất một nửa giây. Và hướng khác nếu bạn có một danh sách thực sự, dài và bạn di chuyển từ trên xuống dưới, nó sẽ siêu nhanh trong nửa giây. –

+0

Cảm ơn lời giải thích này nhưng tôi chỉ cuộn theo chiều rộng toàn trang nên luôn có cùng tốc độ. Tôi đã thử với tham số hoạt hình: NO nhưng nó tiếp tục cuộn ở tốc độ cố định. Tôi cũng đã cố gắng thay đổi hình động UIViewAnimationCurve nhưng nó trông giống nhau. Tôi đang thử giải pháp CAPropertyAnimation tùy chỉnh của Ole. – Diwann

+0

Công trình này tuyệt vời. Nhỏ nitpick mặc dù, nó phải được UIViewAnimationOptionCurveEaseInOut. –

6

Với việc sử dụng các API công cộng, tôi không tin điều này hiện nay là có thể. Giả sử bạn không cần tương tác người dùng trong suốt quá trình hoạt ảnh, bạn nên làm tốt hơn vị trí của các bản xem phụ của UIScrollView (ví dụ: nội dung của chế độ xem cuộn), và sau đó điều chỉnh contentOffset mà không hoạt ảnh khi hoàn thành. Bạn có thể làm như vậy:

- (void) scrollToPage:(int)page { 
    UIScrollView *scrollView = contentView; 
    scrollView.userInteractionEnabled = NO; 
    CGPoint offset = CGPointMake(scrollView.bounds.size.width * page, scrollView.contentOffset.y); 
    CGFloat delta = offset.x - scrollView.contentOffset.x; 

    __block int animationCount = 0; 
    for (UIView *view in scrollView.subviews) { 
     [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 
      animationCount++; 
      CGRect frame = view.frame; 
      frame.origin.x -= delta; 
      view.frame = frame; 
     } completion:^(BOOL finished) { 
      animationCount--; 
      if (animationCount == 0) { 
       scrollView.contentOffset = offset; 
       for (UIView *view in scrollView.subviews) { 
        CGRect frame = view.frame; 
        frame.origin.x += delta; 
        view.frame = frame; 
       } 
       scrollView.userInteractionEnabled = YES; 
      } 
     }]; 
    } 
} 

Tôi có thể xác nhận điều này hoạt động như mong đợi, tôi đã tự mình thử nghiệm.

+0

Vâng, đó là một giải pháp thay thế thú vị. Nhưng tôi cần phải sử dụng giá trị contentOffset thời gian thực để di chuyển chế độ xem của tôi bên trong scrollview trong khi cuộn và giải pháp này không trig scrollviewdidscroll. – Diwann

+0

Vâng, nó sẽ kích hoạt 'scrollViewDidScroll' khi bạn đặt' contentOffset' ở cuối. Nhưng bạn chỉ có thể trích xuất bất kỳ xử lý thêm nào bạn thực hiện trong 'scrollViewDidScroll' và thay vào đó sử dụng nó trong phương thức này. –

+0

Ngoài ra, bạn có thể nhúng tất cả các bản tóm tắt 'UIScrollView' của bạn vào một' UIView' khác, mà bạn có thể phân lớp và ghi đè 'setFrame:', vì trong một hoạt ảnh, nó sẽ cơ bản tương đương với 'scrollViewDidScroll'. –

4
[UIView animateWithDuration:(Animation_Duration) 
          delay:0.0 
         options:UIViewAnimationOptionCurveEaseInOut 
        animations:^{ 
        [scroll setContentOffset:CGPointMake(PointX, PointY) animated:NO]; 
         } 
        completion:^(BOOL finished){}];` 
3

Lớp này hoàn toàn đã cứu sống tôi:

MOScroll on GitHub.com

Nó có

- (void)setContentOffset:(CGPoint)contentOffset withTimingFunction:(CAMediaTimingFunction *)timingFunction duration:(CFTimeInterval)duration;

Cũng giống như các API riêng nhưng với tất cả các phương pháp công cộng và toán.

+0

Liên kết hoạt động cho MOScroll: https://github.com/plancalculus/MOScrollView – Koen

Các vấn đề liên quan