2009-08-27 36 views

Trả lời

-3

Vâng, nếu bạn muốn thực hiện một hành động khi scrollToRowAtIndexPath đã được kích hoạt.

- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated 

Bạn cần phải tạo một con trỏ CAAnimation như

CAAnimation *myAnimation; 

Sau đó thiết lập các delgate tự

myAnimation.delegate = self; 

Khi bạn làm điều đó, những phương pháp đại biểu sau đây cần kích hoạt, nơi bạn có thể đặt mã của bạn:

- (void)animationDidStart:(CAAnimation *)theAnimation 

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag 
+5

làm thế nào bạn initialising 'con trỏ myAnimation' của bạn? –

27

mẫu cơ bản:

[UIView animateWithDuration:0.2 animations:^{ 
    //do some animations, call them with animated:NO 
} completion:^(BOOL finished){ 
    //Do something after animations finished  
}]; 

Ví dụ: Di chuyển đến chèo 100. Khi hoàn tất, lấy tế bào ở hàng này và làm cho xem nội dung di động với thẻ = 1 đến firstResponder:

[UIView animateWithDuration:0.2 animations:^{ 
     [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:100 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
    } completion:^(BOOL finished){ 
     //Do something after scrollToRowAtIndexPath finished, e.g.: 
     UITableViewCell *nextCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:100 inSection:0]]; 
     [[nextCell.contentView viewWithTag:1] becomeFirstResponder];   
    }]; 
+0

Đây là câu trả lời rõ ràng nhất về SO cho "Cách thực hiện X sau khi scrollToRowAtIndexPath hoàn tất?" Cảm ơn! –

+1

Tôi không biết làm thế nào giải pháp này đã được làm việc trên iOS 4/5 nhưng bây giờ trên iOS 6.1.4 và tôi nhận thấy rằng ngay sau khi contentOffset được thay đổi bởi scrollToRowAtIndexPath, các ô ở vị trí này không hiển thị, vì vậy cho một phần thứ hai của tableview là hoàn toàn trống, sau đó các tế bào được rút ra và bàn phím được hiển thị như mong đợi. Tôi đoán một UITableView không có nghĩa là để được sử dụng theo cách này, hoặc ít nhất là không có trong phiên bản iOS này. Kết quả tương tự cũng xảy ra khi sử dụng setContentOffset thay vì scrollToRowAtIndexPath. – ggould75

+0

Tôi không nghĩ rằng điều này là làm việc – shim

2

tôi nhận ra điều này một bài cũ nhưng tôi đã có một vấn đề tương tự và tạo ra một giải pháp mà làm việc tốt cho tôi. Tôi đã áp dụng các kỹ thuật được sử dụng trên NSCookBook để tạo UIAlertView với các khối. Lý do tôi đã đi cho điều này là bởi vì tôi muốn sử dụng hình ảnh động tích hợp hơn là UIView's + animateWithDuration: animations: completion :. Có sự khác biệt lớn hơn giữa các hoạt ảnh này với thay đổi đối với iOS 7.

Bạn tạo danh mục cho UITableView và trong tệp triển khai bạn tạo lớp riêng bên trong sẽ gọi lại khối bằng cách gán nó làm đại biểu của tableview. Việc nắm bắt là cho đến khi khối được gọi, đại biểu ban đầu sẽ bị "mất" để nói, vì đại biểu mới là đối tượng sẽ gọi khối. Đó là lý do tại sao tôi đặt một thông báo để gửi một tin nhắn khi khối đã được gọi để gán lại UITableViewDelegate gốc. Mã này đã được thử nghiệm và đang hoạt động trên đầu của tôi.

// Header file 
@interface UITableView (ScrollDelegateBlock) 

-(void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath 
      atScrollPosition:(UITableViewScrollPosition)scrollPosition 
        animated:(BOOL)animated 
       scrollFinished:(void (^)())scrollFinished; 

@end 


// Implementation file 
#import "UITableView+ScrollDelegateBlock.h" 
#import <objc/runtime.h> 

NSString *const BLOCK_CALLED_NOTIFICATION = @"BlockCalled"; 

@interface ScrollDelegateWrapper : NSObject <UITableViewDelegate> 

@property (copy) void(^scrollFinishedBlock)(); 

@end 

@implementation ScrollDelegateWrapper 

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 
    if (self.scrollFinishedBlock) { 
     [[NSNotificationCenter defaultCenter] postNotificationName:BLOCK_CALLED_NOTIFICATION object:nil]; 
     self.scrollFinishedBlock(); 
    } 
} 

@end 

static const char kScrollDelegateWrapper; 

static id<UITableViewDelegate>previousDelegate; 

@implementation UITableView (ScrollDelegateBlock) 

-(void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath 
      atScrollPosition:(UITableViewScrollPosition)scrollPosition 
        animated:(BOOL)animated 
       scrollFinished:(void (^)())scrollFinished { 
    previousDelegate = self.delegate; 
    ScrollDelegateWrapper *scrollDelegateWrapper = [[ScrollDelegateWrapper alloc] init]; 
    scrollDelegateWrapper.scrollFinishedBlock = scrollFinished; 
    self.delegate = scrollDelegateWrapper; 

    objc_setAssociatedObject(self, &kScrollDelegateWrapper, scrollDelegateWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 

    [self scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(blockCalled:) 
               name:BLOCK_CALLED_NOTIFICATION 
               object:nil]; 
} 

/* 
* Assigns delegate back to the original delegate 
*/ 
-(void) blockCalled:(NSNotification *)notification { 
    self.delegate = previousDelegate; 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                name:BLOCK_CALLED_NOTIFICATION 
                object:nil]; 
} 

@end 

Sau đó bạn có thể gọi phương thức giống như bất kỳ khác với một khối:

[self.tableView scrollToRowAtIndexPath:self.currentPath 
          atScrollPosition:UITableViewScrollPositionMiddle 
            animated:YES 
          scrollFinished:^{ 
           NSLog(@"scrollFinished"); 
          } 
]; 
+0

Cảm ơn bạn đã đăng bài này.Đã chuyển đổi nó sang chế độ xem bộ sưu tập của tôi và hoạt động hoàn hảo. – Augie

+2

lưu ý nhanh: nếu scrollview đã ở trên cùng, khối hoàn thành không kích hoạt. cần phải kiểm tra vị trí đầu tiên. – Augie

+0

Điều này hoạt động, tuy nhiên nó dường như bỏ qua các heightForCell trong/sau khi di chuyển. Tôi có một ô nhỏ hơn ở cuối mỗi phần, tuy nhiên phương pháp này làm cho các ô nhỏ hơn có cùng kích thước với tất cả các ô khác. – Darren

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