2009-05-11 12 views
103

Mi stavo battendo la testa su questo, e Google non stava rilevando nulla. Alla fine ho lavorato e ho pensato di scriverlo qui per il bene della prossima persona.Come limitare il riordino delle righe di UITableView a una sezione

Hai un UITableView con più sezioni. Ogni sezione è omogenea, ma la tabella generale è eterogenea. Pertanto, potresti voler consentire il riordino delle righe all'interno di una sezione, ma non lo nelle sezioni. Forse vuoi anche solo volere che una sezione sia riordinabile (era il mio caso). Se stai cercando, come ero io, allo UITableViewDataSourceDelegate non troverai una notifica per quando è in procinto di farti spostare una riga tra le sezioni. Ne prendi uno quando inizia a spostare una riga (che va bene) e uno quando è già stato spostato e hai la possibilità di sincronizzarti con le tue cose interne. Non d'aiuto.

Quindi, come è possibile evitare riordini tra le sezioni?

Pubblicherò ciò che ho fatto come risposta separata, lasciandolo aperto a qualcun altro per pubblicare una risposta ancora migliore!

+1

A quale notifica si riferisce quando si dice "si ottiene uno quando inizia a spostare una riga"? Non ne vedo uno, ma spero di discernere quando inizierà il riordino delle cellule. – TomSwift

risposta

61

Abbastanza semplice, davvero.

L'UITableViewDelegate ha il metodo:


tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: 

Questo viene chiamato mentre l'utente è in bilico su un potenziale punto di caduta. Hai la possibilità di dire "no, non lasciarlo lì, lascialo qui invece". È possibile restituire un percorso dell'indice diverso da quello proposto.

Tutto ciò che ho fatto è stato controllare se gli indici delle sezioni corrispondono. Se lo fanno poi bene, restituisci il percorso proposto. in caso contrario, restituire il percorso di origine. Questo impedisce anche alle righe di altre sezioni di spostarsi mentre si trascina, e la riga trascinata tornerà alla posizione originale in cui si tenta di spostarla in un'altra sezione.


- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath 
{ 
    if(sourceIndexPath.section != proposedDestinationIndexPath.section) 
    { 
     return sourceIndexPath; 
    } 
    else 
    { 
     return proposedDestinationIndexPath; 
    } 
} 
+0

Facendo esattamente questo, si verificano alcuni bug di visualizzazione davvero strani sul mio setup, ed è notevolmente diverso dal codice di esempio di Apple su come farlo. FWIW! non dicendo che è sbagliato, solo che mi chiedo se sia effettivamente più complicato di così. –

+0

Posso trascinare una riga in un'altra sezione anche se quella riga non viene impostata lì. ma è visibile quando agli altri con forza.? qualche idea – Sandy

163

Questa implementazione impedirà riordino al di fuori della sezione originale, come la risposta di Phil, ma sarà anche possibile scattare il record per la prima o l'ultima riga della sezione, a seconda di dove la resistenza è andato, invece di dove è iniziato.

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath 
{ 
    if (sourceIndexPath.section != proposedDestinationIndexPath.section) { 
    NSInteger row = 0; 
    if (sourceIndexPath.section < proposedDestinationIndexPath.section) { 
     row = [tableView numberOfRowsInSection:sourceIndexPath.section] - 1; 
    } 
    return [NSIndexPath indexPathForRow:row inSection:sourceIndexPath.section];  
    } 

    return proposedDestinationIndexPath; 
} 
+0

C'è un modo per impedire alla tabella di scorrere automaticamente (mentre si trascina una cella) al di fuori della sezione consentita? – Palimondo

+0

In Xamarin, il metodo wrapper è 'UIKit.UITableViewController.CustomizeMoveTarget', per chiunque si chieda. – bunkerdive

4

Rispetto a @Jason Harwig, il codice riportato di seguito funziona correttamente.

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath 
    { 
     if (sourceIndexPath.section != proposedDestinationIndexPath.section) { 
     NSInteger row = 0; 
     if (sourceIndexPath.section < proposedDestinationIndexPath.section) { 
      row = [tableView numberOfRowsInSection:sourceIndexPath.section] - 1; 
     } 
     return [NSIndexPath indexPathForRow:row inSection:sourceIndexPath.section];  
     } 

     return proposedDestinationIndexPath; 
    } 
7

È possibile impedire lo spostamento di righe tra le sezioni utilizzando il metodo riportato di seguito. Basta non consentire alcun movimento tra le sezioni. È anche possibile controllare lo spostamento di una riga specifica all'interno di una sezione. per esempio l'ultima riga in una sezione.

Ecco l'esempio:

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath { 

    // Do not allow any movement between section 
    if (sourceIndexPath.section != proposedDestinationIndexPath.section) { 
     return sourceIndexPath; 
    } 
    // You can even control the movement of specific row within a section. e.g last row in a  Section 

    // Check if we have selected the last row in section 
    if (sourceIndexPath.row < sourceIndexPath.length) { 
     return proposedDestinationIndexPath; 
    } 
    else { 
     return sourceIndexPath; 
    } 
} 
16

Swifty versione rapida di risposta di Jason per voi i più pigri:

override func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath { 
    if sourceIndexPath.section != proposedDestinationIndexPath.section { 
     var row = 0 
     if sourceIndexPath.section < proposedDestinationIndexPath.section { 
      row = self.tableView(tableView, numberOfRowsInSection: sourceIndexPath.section) - 1 
     } 
     return NSIndexPath(forRow: row, inSection: sourceIndexPath.section) 
    } 
    return proposedDestinationIndexPath 
} 
+2

Mi sentivo davvero pigro, quindi grazie. – iamlolz

1

Swift 3:

override func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath { 
    if sourceIndexPath.section != proposedDestinationIndexPath.section { 
     var row = 0 
     if sourceIndexPath.section < proposedDestinationIndexPath.section { 
      row = self.tableView(tableView, numberOfRowsInSection: sourceIndexPath.section) - 1 
     } 
     return IndexPath(row: row, section: sourceIndexPath.section) 
    } 
    return proposedDestinationIndexPath 
} 
0

Per non cambiare posizione tra le sezioni Swift3

override func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath { 
    if originalIndexPath.section != proposedIndexPath.section 
    { 
     return originalIndexPath 
    } 
    else 
    { 
     return proposedIndexPath 
    } 
} 
Problemi correlati