2012-02-12 14 views
16

Sto cercando di rendere i miei dati Core supportati UITableView ha capacità di riordino, Dopo aver implementato tutti i delegati e qualche tecnica per i dati di base menzionati here ho trovato un comportamento strano. Dopo aver toccato il pulsante di modifica, l'icona di riordino viene visualizzata correttamente e posso toccarla, l'ombra viene visualizzata, ma quando provo a spostarla su un'altra riga, improvvisamente perdo la messa a fuoco e la cella torna al suo posto. Qualcuno conosce la causa di questo problema?Impossibile trascinare UITableViewCell dalla sua posizione corrente durante il riordino

Qui è il video che mostra il problema

http://www.youtube.com/watch?v=ugxuLNL7BnU&feature=youtu.be

Ecco il mio codice

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return YES; 
} 

in -tableView:moveRowAtIndexPath:toIndexPath Ho provato il codice qui sotto e solo un'implementazione vuota, ma il problema esistono ancora, quindi non penso che questo non sia un problema.

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 
{ 
    _changeIsUserDriven = YES; 

    NSUInteger fromIndex = sourceIndexPath.row; 
    NSUInteger toIndex = destinationIndexPath.row; 

    NSMutableArray *newsArray = [[self.fetchedResultsController fetchedObjects] mutableCopy]; 
    News *news = [self.fetchedResultsController.fetchedObjects objectAtIndex:fromIndex]; 

    [newsArray removeObject:news]; 
    [newsArray insertObject:news atIndex:toIndex]; 

    int i = 1; 
    for (News *n in newsArray) { 
     n.displayOrder = [NSNumber numberWithInt:i++]; 
    } 

    [self saveContext]; 

    _changeIsUserDriven = NO; 
} 

FetchedResultController delegato

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
    { 
     if (_changeIsUserDriven) { 
      return; 
     } 
     [self.tableView beginUpdates]; 
    } 




     - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
        atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type 
     { 
      if (_changeIsUserDriven) { 
       return; 
      } 
      switch(type) { 
       case NSFetchedResultsChangeInsert: 
        [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
        break; 

       case NSFetchedResultsChangeDelete: 
        [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
        break; 
      } 
     } 


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    if (_changeIsUserDriven) { 
     return; 
    } 
    UITableView *tableView = self.tableView; 

    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
      break; 

     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 

    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
    { 
     if (_changeIsUserDriven) { 
      return; 
     } 
     [self.tableView endUpdates]; 
    } 
+0

Hai implementato 'tableView commitEditingStyle: forRowAtIndexPath:' e implementa il caso 'UITableViewCellEditingStyleInsert' per aggiornare l'origine dati e spostare effettivamente la riga (o' reloadData')? – lnafziger

+0

Io uso i dati di base e fetchedResultController per questo e tutta la parte di salvataggio viene eseguita in '- (void) tableView: moveRowAtIndexPath: toIndexPath:' – sarunw

+0

Ok, ora che c'è più codice: – lnafziger

risposta

18

finalmente ho trovato il problema, perché la sua libreria esterna che uso, IIViewDeckController, dopo rimuove che il problema va via.

+5

Se si desidera mantenere 'IIViewDeckController', è possibile risolvere questo problema disabilitando la modalità panning: 'viewDeck.panningMode = IIViewDeckNoPanning;' – rbrown

+0

Ho appena avuto lo stesso problema, e questo ha risolto il mio problema. Tu sei il mio eroe. – JRod

+3

Ho avuto lo stesso problema con '' ECSlidingViewController''. Rimuovendo temporaneamente il gesto di scorrimento con '' [self.view removeGestureRecognizer: self.slidingViewController.panGesture]; '' ho risolto questo problema per me. – smek

3

Ciò è dovuto al ViewDeckController. Sto usando una porta in MonoTouch e continuo a riscontrare il problema. È dovuto (più specificamente) a UIPanGestureRecognizer. Il riconoscitore di gesti prende in mano il movimento pan/trascina e crede che sia pensato per se stesso, quindi annulla il tocco inviato a UITableView.

Sfortunatamente, non esiste una proprietà UIPanGestureRecognizer.direction (orizzontale/verticale), ma qui c'è un post: UIPanGestureRecognizer - Only vertical or horizontal su come limitare il gesto di panoramica a una determinata direzione. Sarà necessario modificare il codice ViewDeckController dove aggiunge UIPanGestureRecognizer per utilizzare la versione sottoclasse dalla domanda precedente.

Non ho ancora testato questo (come il suo 2 e im fatto per oggi!), Ma aggiornerò la mia risposta una volta che ho avuto il tempo di implementare questo.

Come una soluzione rapida e sporca, è possibile impostare

panner.cancelsTouchesInView = NO; 

Questo vi permetterà di spostare i tuoi articoli, ma avrà anche il risultato previsto di non annullando tocchi nella vista, quindi, a seconda il contenuto della tua vista centrale, potrebbe far sì che i tuoi utenti premano un pulsante quando hanno intenzione di far scorrere il riquadro della vista verso il lato.

Un'altra possibilità sarebbe quella di impostare questa proprietà su NO quando si imposta la tabella in modalità di modifica e di tornare a SÌ dopo aver terminato.

Problemi correlati