2009-08-27 18 views

risposta

-3

Bene se si desidera eseguire un'azione una volta che è stato attivato lo scrollToRowAtIndexPath.

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

È necessario creare un puntatore CAAnimation come

CAAnimation *myAnimation; 

Quindi impostare il delgate di auto

myAnimation.delegate = self; 

Una volta fatto questo, questi seguenti metodi delegato dovrebbe attivare dove si può mettere il tuo codice:

- (void)animationDidStart:(CAAnimation *)theAnimation 

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

come stai inizializzazione vostro 'puntatore myAnimation'? –

27

modello di base:

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

Esempio: Scorrere fino a remare 100. Al termine, ottenere la cella a questa riga e rendere la vista dei contenuti cella con tag = 1 alla 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

Questa è di gran lunga la risposta più pulita su SO per "Come eseguire X dopo aver completato scrollToRowAtIndexPath?" Grazie! –

+1

Non so come funzionasse questa soluzione su iOS 4/5 ma ora su iOS 6.1.4 e sto notando che subito dopo che contentOffset è stato modificato da scrollToRowAtIndexPath, le celle in questa posizione non sono visibili, quindi per un frazione di secondo il tableview è completamente vuoto, quindi le celle vengono disegnate e la tastiera viene visualizzata come previsto. Immagino che un UITableView non debba essere usato in questo modo, o almeno non in questa versione di iOS. Lo stesso risultato si verifica utilizzando setContentOffset anziché scrollToRowAtIndexPath. – ggould75

+0

Non penso che funzioni – shim

2

I rendersi conto di questo vecchio post ma stavo avendo un problema simile e ho creato una soluzione che funzionava bene per me. Ho applicato le tecniche utilizzate su NSCookBook per la creazione di UIAlertViews con blocchi. Il motivo per cui ho optato per questo è stato perché volevo utilizzare le animazioni integrate piuttosto che quelle di UIView + animateWithDuration: animations: completion :. C'è una maggiore differenza tra queste animazioni con la modifica a iOS 7.

Si crea una categoria per UITableView e nel file di implementazione si crea una classe privata interna che richiamerà il blocco assegnandolo come delegato della propria tabella. Il problema è che finché il blocco non viene chiamato, il delegato originale verrà "perso" per così dire, dal momento che il nuovo delegato è l'oggetto che chiamerà il blocco. Questo è il motivo per cui ho inviato una notifica per inviare un messaggio quando il blocco è stato chiamato per riassegnare l'UITableViewDelegate originale. Questo codice è stato testato e sta lavorando alla mia fine.

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

È quindi possibile chiamare il metodo come un altro con un blocco:

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

Grazie per aver postato questo.Convertito nella mia vista collezione e funziona perfettamente. – Augie

+2

quick note: se la scrollview è già in cima, il blocco di completamento non si attiva. è necessario controllare prima la posizione. – Augie

+0

Funziona, tuttavia sembra ignorare l'altezza di ForCell durante/dopo la pergamena. Ho una cella più piccola nella parte inferiore di ogni sezione, tuttavia questo metodo rende le celle più piccole della stessa dimensione di tutte le altre. – Darren

Problemi correlati