2013-11-22 3 views
6

Ho una vista tabella che visualizza i messaggi che prelevo dalla rete.TableView scorre al centro quando viene inserita una nuova riga

Quando arriva un nuovo messaggio, deve essere aggiunto a tableview in basso.

Quando arriva un nuovo messaggio, viene aggiunto correttamente nella parte inferiore della vista tabella, ma la vista tabella scorre immediatamente al centro. (Quindi se avessi detto 100 celle lì ora, la cella 50 sarebbe nel mezzo della vista di scorrimento ora).

La cosa strana è che ciò accade solo se il punto di scorrimento prima dell'inserto si trova nella metà inferiore della tabella.

Quindi, se guardo la cella 10 di 99, e aggiungo una riga, essa viene aggiunta in fondo bene.

Ma, se guardo la cella 75 di 99 e aggiungo una riga, la posizione di scorrimento salta nuovamente al centro (~ cella 50).

Ecco il mio codice per l'aggiunta di un nuovo messaggio alla Tableview:

[self.tableView beginUpdates]; 
[self.messages addObject:message]; 

NSArray *indexPaths = @[[NSIndexPath indexPathForRow:(self.messages.count - 1) inSection:0]]; 

[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade]; 
[self.tableView endUpdates]; 

Perché tableView Scorrimento automatico in questo modo?

+0

Non si vuole far scorrere la vostra Tableview ?? –

+0

@hussainShabbir Scorre senza alcuna interazione dell'utente. Quando aggiungo una nuova riga, non voglio che scorra automaticamente al centro, cosa che sta facendo ora. – Jeff

+0

@Jeff Hai avuto fortuna con la risoluzione di questo? Ho lo stesso problema. Usare le celle auto dimensionanti e sta saltando come un matto. –

risposta

0

penso che è necessario modificare l'animazione fila per NONE-

[self.tableView 
insertRowsAtIndexPaths:indexPaths 
withRowAnimation: 
UITableViewRowAnimationNone]; 
+0

Ho provato tutti i tipi di animazione, tutti con lo stesso risultato: il tableview scorre al centro dopo l'inserimento. – Jeff

0

Prova questa

[self.tableView scrollToRowAtIndexPath:indexpath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

inoltre è possibile modificare la posizione di Middile, in alto o nessuno.

0

Anche io ho questo problema. NSTableView e UITableView sono probabilmente simili ... il loro comportamento di scorrimento predefinito sia SUCK. TableView non è progettato per essere usato come un editor di stile foglio di calcolo, migliaia così nel corso degli anni ho aggiunto di righe di codice per renderlo lavoro sorta di come un foglio di calcolo. Vorrei che Apple potrebbe semplicemente creare una sottoclasse NSSpreadsheetView di NSTableView per risolvere tutta questa roba: - tasti cursore navigare cellule - il comportamento di scorrimento sensibile - aggiunge hoc selezione cella

Vorrebbe anche vedere una sottoclasse NSLogView di NSTableView che si comporta come Console.app, con un campo di ricerca.

La mia soluzione era di aggiungere diversi metodi categoria:

@implementation NSTableView (VNSTableViewCategory) 

-(NSInteger)visibleRow 
{ 
    NSRect theRect = [self visibleRect]; 
    NSRange theRange = [self rowsInRect:theRect]; 
    if (theRange.length == 0) 
     return -1; 
    else if (NSLocationInRange([self editedRow], theRange)) 
     return [self editedRow];   
    else if (NSLocationInRange([self clickedRow], theRange)) 
     return [self clickedRow];  
    else if (NSLocationInRange([self selectedRow], theRange)) 
     return [self selectedRow]; 
    else 
     return theRange.location + (theRange.length/2); 
} 

-(NSRange)visibleRows 
{ 
    NSRect theRect = [self visibleRect]; 
    NSRange theRange = [self rowsInRect:theRect]; 
    return theRange; 
} 

-(void)scrollRowToVisibleTwoThirds:(NSInteger)row 
{ 
    NSRect theVisRect = [self visibleRect]; 
    NSUInteger numRows = [self numberOfRows]; 
    NSRange visibleRows = [self rowsInRect:theVisRect]; 
    //NSUInteger lastVisibleRow = NSMaxRange(visibleRows); 
    if (NSLocationInRange(row, visibleRows)) 
    { 
     if (row - visibleRows.location < (visibleRows.length * 2/3)) 
     { 
     // may need to scroll up 
     if (visibleRows.location == 0) 
      [self scrollRowToVisible:0]; 
     else if ((row - visibleRows.location) > 2) 
      return; 
     } 
    } 

    NSRect theRowRect = [self rectOfRow:row]; 

    NSPoint thePoint = theRowRect.origin; 
    thePoint.y -= theVisRect.size.height/4; // scroll to 25% from top 

    if (thePoint.y < 0) 
     thePoint.y = 0; 

    NSRect theLastRowRect = [self rectOfRow:numRows-1]; 
    if (thePoint.y + theVisRect.size.height > NSMaxY(theLastRowRect)) 
     [self scrollRowToVisible:numRows-1]; 
    else 
    { 
     [self scrollPoint:thePoint]; // seems to be the 'preferred' method of doing this 

     // kpk note: these other approaches cause redraw artifacts in many situations: 
//  NSClipView *clipView = [[self enclosingScrollView] contentView]; 
//  [clipView scrollToPoint:[clipView constrainScrollPoint:thePoint]]; 
//  [[self enclosingScrollView] reflectScrolledClipView:clipView]; 
//  [self scrollRowToVisible:row]; 

//  [[[self enclosingScrollView] contentView] scrollToPoint:thePoint]; 
//  [[self enclosingScrollView] reflectScrolledClipView:[[self enclosingScrollView] contentView]];  
    } 

} 
@end // NSTableView (VNSTableViewCategory) 

Esempio di utilizzo:

NSRange visRows = [toScenesTable visibleRows]; 
    visRows.length -= 2; 
    if (iAlwaysScroll == YES || !NSLocationInRange(row, visRows)) 
    { 
    [toScenesTable scrollRowToVisibleTwoThirds:row]; // VNSTableViewCategory 
    }