2016-02-07 13 views
8

ho una visione tavolo correttamente configurato per avere l'altezza delle righe dinamiche sulla base di guida di Ray Wenderlich trovato here:UITableViewController: Scorrendo verso il basso con l'altezza delle righe dinamica inizia animazione alla posizione sbagliata

ho creato i vincoli di avere una chiara linea di vincoli dalla parte superiore alla parte inferiore della cella. Ho anche impostato le priorità di contenimento del contenuto e di resistenza alla compressione del contenuto e l'altezza della riga stimata.

Questo è il codice che uso per impostare la visualizzazione della tabella:

func configureTableView() { 
    // its called on viewDidLoad() 
    tableView.rowHeight = UITableViewAutomaticDimension 
    tableView.estimatedRowHeight = 100.0 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    configureTableView() 

    for i in 1...20 { 
     messages.append([ 
      "title": "foo \(i)", 
      "message": "bla \(i)\nbla\nbla" 
     ]) 
    } 

    // this is because the actual row heights are not available until the next layout cycle or something like that 
    dispatch_async(dispatch_get_main_queue(), {self.scrollToBottom(false)}) 
} 

func scrollToBottom(animated:Bool) { 
    let indexPath = NSIndexPath(forRow: self.messages.count-1, inSection: 0) 

    self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated) 
} 

e questo è come aggiungo nuove righe:

@IBAction func addMore(sender:UIBarButtonItem) { 
    let message = [ 
     "title": "haiooo", 
     "message": "silver"] 

    messages.append(message) 

    let indexPath = NSIndexPath(forRow: messages.count-1, inSection: 0) 

    tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Bottom) 

    scrollToBottom(true) 
} 

Il setup con le file di default vanno bene. Aggiunge le righe e scorre verso il basso come previsto.

Ma quando aggiungo nuove righe, lo scorrimento sembra iniziare sopra l'ultima cella. Mentre aggiungo più celle, l'offset sembra aumentare.

Ecco una gif mostrando che ciò accada: Imgur

E 'certamente legato al l'animazione di scorrimento (non l'animazione insertRow) perché scorre correttamente quando l'animazione è spento.

La modifica dello estimatedRowHeight fa la differenza sullo scostamento di scorrimento, ma non è stato possibile trovare un valore che lo ha corretto.

Ho anche provato a ritardare lo scorrimento utilizzando dispatch_async ma non ha modificato nulla.

Ragazzi, avete qualche idea?

+0

Dal video non posso dire cosa c'è che non va. E non capisco cosa significhi "... lo scorrimento sembra iniziare sopra l'ultima cellula". Potresti chiarire? Anche rendere disponibile un progetto di esempio con il problema potrebbe essere utile. –

+0

Dave, nota come le celle 17 e 18 continuano a essere visualizzate nella parte superiore dello schermo all'avvio del rotolo, quando sono già al di fuori dell'area visibile della vista tabella. Sembra che lo schermo si sollevi prima di iniziare l'animazione. Puoi trovare il codice sorgente qui: https://github.com/marcio0/ios-playground/tree/master/scrolltest –

+0

OK, posso vederlo nel video ora (se lo scarico e vado fotogramma -telaio). Ma non lo vedo nel progetto di esempio. Ho provato diversi modelli di telefono (ma tutti i 9.2) e ho anche provato a rallentare le animazioni, ma non ho mai visto il problema che stai riscontrando. –

risposta

13

Wow, è stata una sfida divertente. Grazie per aver pubblicato il progetto di test.

Quindi sembra che dopo aver aggiunto la nuova riga ci sia qualcosa in comune con la tabella in cui si pensa di scorrere. Mi sembra un bug in UIKit. Quindi, per ovviare a ciò, ho aggiunto del codice per "ripristinare" la vista tabella prima di applicare l'animazione.

Ecco cosa ho finito con:

@IBAction func addMore(sender:UIBarButtonItem) { 
    let message = [ 
     "title": "haiooo", 
     "message": "silver"] 
    messages.append(message) 

    tableView.reloadData() 

    // To get the animation working as expected, we need to 'reset' the table 
    // view's current offset. Otherwise it gets confused when it starts the animation. 
    let oldLastCellIndexPath = NSIndexPath(forRow: messages.count-2, inSection: 0) 
    self.tableView.scrollToRowAtIndexPath(oldLastCellIndexPath, atScrollPosition: .Bottom, animated: false) 

    // Animate on the next pass through the runloop. 
    dispatch_async(dispatch_get_main_queue(), { 
     self.scrollToBottom(true) 
    }) 
} 

non ho potuto farlo funzionare con insertRowsAtIndexPaths(_:withRowAnimation:), ma reloadData() funzionato bene. Quindi è necessario lo stesso ritardo prima di animare alla nuova ultima riga.