2012-11-02 1 views
6

Sto tentando di simulare il comportamento del testo del fumetto iMessage con un UITableView. Per scorrere sempre verso il basso, sto usando scrollToRowAtIndexPath quando viewDidLoad e viewDidAppear. Questo perché quando viene chiamato il metodo viewDidLoad, la tabella non è stata caricata completamente, quindi ho bisogno di quella scroll aggiuntiva in viewDidAppear. Questo codice rende il trucco. Tuttavia, ciò che voglio non è uno scorrimento animato (l'impostazione di animated a NO non risolve questo problema), voglio che la tabella sia sempre visualizzata dal basso, non carichi la tabella e poi vai all'ultima riga.Caricare UITableView dal basso

È possibile? Non riesco a trovare nessuna soluzione che si adatti perfettamente al comportamento desiderato.

+0

Si potrebbe provare a capovolgere la visualizzazione della tabella con un 180 °, capovolgere il celle di visualizzazione tabella personalizzate di 180 ° in modo da sembrare normali e invertire la logica per i percorsi indice. Avresti la riga 0 nella parte inferiore della tua tableview. – Moxy

+0

Sembra un sacco di lavoro. Basta invertire la tua origine dati cambiando l'ultimo oggetto per il primo oggetto e così via. Quindi lo visualizzerai in ordine inverso. – Martol1ni

+0

@ Martol1ni Sono solo 2 righe di codice! – Moxy

risposta

8

È possibile evitare la chiamata da viewDidLoad poiché lo scorrimento dall'interno di viewDidAppear rende ridondante la prima chiamata. viewDidAppear viene chiamato ogni volta che si torna alla vista ma viewDidLoad viene chiamato una sola volta quando viene inizializzata la vista.

Concordo con i suggerimenti precedenti di nascondere lo scroll all'utente invece di modificare il modo in cui UITableView sta caricando i dati. Il mio suggerimento sarebbe quello di utilizzare il metodo scrollToRowAtIndexPath nel metodo viewWillAppear con l'animazione impostata su NO. Dopodiché, se devi aggiungere una nuova riga mentre la tabella è visibile all'utente, usa insertRowsAtIndexPaths: withRowAnimation: per aggiungere una riga nella parte inferiore della vista tabella. Assicurati di aver cura di aggiungere i dati alla fine del tuo modello di dati in modo che quando l'utente si allontana e ritorni, torna allo stesso layout.

Spero che questo aiuti.

modifica: Ho appena visto il tuo motivo per non accettare le risposte precedenti e ho pensato di elaborare un po 'di più. La soluzione che propongo richiederebbe uno sforzo minimo, evitando di chiamare ripetutamente reloadData e quindi evitare di chiamare ripetutamente il metodo scrollToRowAtIndexPath. Devi solo effettuare una chiamata a scrollToRowAtIndexPath in viewWillAppear per scorrere fino alla fine della vista tabella (nascondendo la transizione da utente quando lo fai) e non avresti bisogno di farlo di nuovo.

+0

Accetto questa risposta perché @NumanTariq è stato il primo a indicare che l'aggiornamento dovrebbe essere fatto in 'viewWillAppear'. – amb

+0

ma prima di scorrere è necessario inserire il metodo reloadData che fa apparire l'effetto lampeggiante dell'animazione. come risolvere per la prima volta entrare nello schermo e aggiungere dati nell'array e caricare la tabella e scorrere verso il basso senza alcun effetto di lampeggio. –

1

È possibile avere il UITableView nascosto su viewDidLoad, quindi modificarlo in visibile su viewDidAppear subito dopo averlo spostato verso il basso. In questo modo l'utente non vedrà l'animazione a scorrimento.

0
scrollToRowAtIndexPath 

uso per scorrere la riga in Tableview alla posizione particolare

1

È possibile risolvere il problema di fare footer invisibile e fare i calcoli in là. Quando il piè di pagina viene caricato, contentSize viene aggiornato. Per farlo scorrere, spunta il contentOffset di tableview.

Ho commentato la parte dell'animazione, dal momento che l'hai voluta senza, ma funziona anche.

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 
{ 
    return 1; 
} 

-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section 
{ 
    if(tableView.contentOffset.y != tableView.contentSize.height - tableView.frame.size.height && automaticScroll){ 

     //[UIView animateWithDuration:0.0 animations:^{ 

      self.contentTableView.contentOffset = CGPointMake(0, tableView.contentSize.height - self.contentTableView.frame.size.height); 

     //} completion:^(BOOL finished) { 

      [tableView reloadData]; 

     //}]; 

     automaticScroll = NO; 
    } 

    UIView *emptyFooter = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)]; 
    emptyFooter.backgroundColor = [UIColor clearColor]; 
    return emptyFooter; 
} 

Ho creato un BOOL automaticScroll per attivare lo scorrimento verso il basso. Questo dovrebbe essere impostato nel metodo viewWillAppear o ogni volta che carichi i dati e ricarichi tableView.

Se si desidera aggiungere righe, è anche necessario impostare la BOOL, come:

-(void)addItemButtonClicked:(id)sender 
{ 
    automaticScroll = YES; 
    //Add object to data 
    [self.contentTableView reloadData]; 
} 

Se avete bisogno di più aiuto, per favore fatemelo sapere.

4

Faccio qualcosa di simile in un calcolatore RPN che ho creato.Ho una vista tabella con tutti i numeri in essa e quando un numero viene aggiunto allo stack, tutto si apre su una cella. Quando carico la vista chiamo:

[self.myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:NumOfStackItems - 1 inSection:0] 
         atScrollPosition:UITableViewScrollPositionTop animated:NO]; 

Nella mia viewWillAppear. In questo modo, la visualizzazione della tabella inizia in fondo alla pila e non viene visualizzata alcuna animazione. Inserendo questo nella viewWillAppear, ogni volta che si accede alla vista, viene visualizzato nella parte inferiore della tabella.

Quando aggiungo i numeri allo stack, ho appena aggiungo in un array che contiene tutti i numeri e poi mettere il testo nella riga appropriata in questo modo:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Cell initialization here... 
    NSUInteger row_num = [indexPath row]; 
    cell.rowNumber.text = [NSString stringWithFormat:@"%g", [DataArray objectAtIndex:NumberOfStackItems-row_num-1];// subtract the row number off to get the correct array index 
    return cell 
} 

Ho anche fare in modo che ogni volta che aggiorna la tableview con un nuovo valore, prima chiamo la funzione reloadData, e poi chiamo la funzione scrollToRowAtIndexPath che ho citato sopra, in questo modo rimango in fondo alla tabella.

2

La soluzione è quella di ignorare viewWillAppear e lasciarlo scorrere (non-animati) per il fondo:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self goToBottom]; 
} 

-(void)goToBottom 
{ 
    NSIndexPath *lastIndexPath = [self lastIndexPath]; 
    [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO]; 
} 

-(NSIndexPath *)lastIndexPath 
{ 
    NSInteger lastSectionIndex = MAX(0, [self.tableView numberOfSections] - 1); 
    NSInteger lastRowIndex = MAX(0, [self.tableView numberOfRowsInSection:lastSectionIndex] - 1); 
    return [NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex]; 
} 

Eseguendo questo a viewWillAppear sarà fatto prima che l'utente vede il tavolo.

17

Questa è la soluzione migliore!

Basta invertire tutto!

tableView.transform = CGAffineTransformMakeRotation(-M_PI); 
cell.transform = CGAffineTransformMakeRotation(M_PI); 

Swift 4.0:

tableView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi) 
cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi) 

Attenzione però, perché ora le posizioni headerView e footerView sono invertiti pure.

+3

questa è la migliore risposta di sempre! e f ** ing facile! – Quetool

+0

interrompe l'indicatore di scorrimento, ma funziona :) – RolandasR

+1

Questa è una soluzione hacky e causerà problemi lungo la strada se è necessario aggiungere qualsiasi tipo di gesti/azioni di scorrimento alle celle. –

0

modifica appena contenuto dopo aver caricato i dati per spostare la vista del contenuto della vista tabella se l'altezza è inferiore alla vista padre.

[self.tableView reloadData];   
[self.tableView setContentInset:UIEdgeInsetsMake(self.view.frame.size.height - self.tableView.contentSize.height < 0 ? 0 : self.view.frame.size.height - self.tableView.contentSize.height, 0, 0, 0)]; 
-1

Swift 3,0

// Rotate 
let rotate = CGAffineTransform(rotationAngle: -(CGFloat)(M_PI)) 

// Move to the left 
let translate = CGAffineTransform(scaleX: -1, y: 1) 

self.tableView.transform = rotate.concatenating(translate) 
0

Swift 3,1

tableView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi)) 
cell.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi)) 

Crediti: @Christos Hadjikyriacou

+1

è meglio fare così 'cell.contentView.transform = CGAffineTransform (rotationAngle: CGFloat (Double.pi))' – douarbou