2009-08-27 11 views

Antwort

-3

Nun, wenn Sie eine Aktion ausführen möchten, sobald der scrollToRowAtIndexPath ausgelöst wurde.

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

Sie müssen die delgate zu sich selbst einen CAAnimation Zeiger wie gesetzt

myAnimation.delegate = self; 

Dann

CAAnimation *myAnimation; 

erstellen Wenn Sie das tun, diese folgenden Delegatmethoden aktivieren sollten, wo Sie setzen können Ihr Code:

- (void)animationDidStart:(CAAnimation *)theAnimation 

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

, wie Sie Ihren 'myAnimation' Zeiger werden initialisiert? –

27

Grund Vorlage:

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

Beispiel: Blättern 100. Wenn Sie fertig sind, bekommen die Zelle in dieser Reihe und machen die Zelleninhalt Ansicht mit dem Tag = 1 zum firstResponder rudern:

[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

Dies ist bei weitem die sauberste Antwort auf SO für "wie X ausführen, nachdem scrollToRowAtIndexPath abgeschlossen ist?" Vielen Dank! –

+1

Ich weiß nicht, wie diese Lösung auf iOS 4/5, aber jetzt auf iOS 6.1.4 funktionierte, und ich stelle fest, dass die Zellen an dieser Position nicht sichtbar sind, also nachdem ein contentOffset durch scrollToRowAtIndexPath geändert wurde Sekundenbruchteilen ist die Tabellenansicht komplett leer, dann werden die Zellen gezeichnet und die Tastatur wird wie erwartet angezeigt. Ich denke, ein UITableView ist nicht dazu gedacht, oder zumindest nicht in dieser Version von iOS verwendet zu werden. Dasselbe Ergebnis passiert mit setContentOffset anstelle von scrollToRowAtIndexPath. – ggould75

+0

Ich glaube nicht, dass das funktioniert – shim

2

I realisierte dies eine alte Post, aber ich hatte ein ähnliches Problem und schuf eine Lösung, die für mich gut funktionierte. Ich habe die Techniken angewendet auf NSCookBook für die Erstellung von UIAlertViews mit Blöcken. Der Grund dafür war, dass ich die integrierten Animationen anstelle von UIView + animateWithDuration verwenden wollte: animations: completion :. Zwischen diesen Animationen besteht bei der Umstellung auf iOS 7 ein größerer Unterschied.

Sie erstellen eine Kategorie für UITableView und in der Implementierungsdatei erstellen Sie eine innere private Klasse, die den Block zurückruft, indem sie ihn als Delegierten Ihrer TableViews zuweist. Der Catch ist, dass der ursprüngliche Delegat sozusagen "verloren" wird, bis der Block aufgerufen wird, da der neue Delegat das Objekt ist, das den Block aufrufen wird. Aus diesem Grund habe ich eine Benachrichtigung gesendet, um eine Nachricht zu senden, wenn der Block aufgerufen wurde, um das ursprüngliche UITableViewDelegate neu zuzuweisen. Dieser Code wurde getestet und arbeitet an meinem Ende.

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

Sie können dann mit einem Block das Verfahren wie jedes andere nennen:

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

Vielen Dank für das Posten.Konvertiert es in meine Sammlung Ansicht und funktioniert perfekt. – Augie

+2

Kurzinfo: Wenn der Scrollview bereits oben ist, wird der Completion-Block nicht ausgelöst. muss zuerst die Position prüfen. – Augie

+0

Dies funktioniert, aber es scheint die heightForCells während/nach dem Scroll zu ignorieren. Ich habe eine kleinere Zelle am unteren Ende jeder Sektion, aber diese Methode macht die kleineren Zellen gleich groß wie alle anderen. – Darren

Verwandte Themen