Domanda UITableView sfarfalla / balbetta durante l'immissione di testo nel ridimensionamento automatico di TextView


Attualmente ho un UITableView con un ridimensionamento UITextView dentro. La cella viene ridimensionata automaticamente utilizzando beginUpdates/endUpdates, ma quando lo fa, la vista della tabella oscilla (vedi la gif in basso).

Il risultato finale è a UITableViewCell che ha una textview in esso che si ridimensiona in base al suo contenuto. Ecco il codice all'interno dell'abitudine UITableViewCell classe che causa il UITableView per aggiornarsi.

- (void)textViewDidChange:(UITextView *)textView {
    // This is a category on UITableViewCell to get the [self superView] as the UITableView
    UITableView *tableView = [self tableView];
    if (tableView){
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}

Ecco le cose che ho già provato:

Ottieni la corrente contentOffset e resettandolo dopo il endUpdates ma non ha funzionato Disabilitare lo scorrimento su UITableView prima degli aggiornamenti e poi l'abilitazione in seguito Ho provato a tornare NO sempre da - (BOOL)textViewShouldEndEditing:(UITextView *)textView Mio UITableView l'altezza della cella sta usando UITableViewAutomaticDimension. Altre idee o pensieri sono benvenuti.

Ecco un esempio di come appare:

Table View Stutter

Non sto cercando di utilizzare alcuna libreria quindi per favore nessun suggerimento per questo.

Grazie

Modifica: soluzione

Trovato qui: Non voglio l'animazione negli aggiornamenti iniziali, il blocco degli aggiornamenti finali per uitableview?

Ringraziamo @JeffBowen per una grande scoperta (anche se hacky è praticabile e mi permette di implementare ancora il UITableViewDelegate metodi per supportare iOS 7). Disattiva le animazioni prima di eseguire l'aggiornamento e poi attiva dopo l'aggiornamento per impedire il UITableView dalla balbuzie.

[UIView setAnimationsEnabled:NO];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled:YES];

Se non hai bisogno di usare i metodi Delegate e vuoi una soluzione meno hacky per iOS 8+, allora vai con la risposta di @Marmaker qui sotto.


16
2017-12-13 15:51


origine


risposte:


La mia soluzione (per iOS 8) è stata impostata per la prima volta nel mio viewController viewDidLoad

self.tableView.rowHeight = UITableViewAutomaticDimension;
// this line is needed to cell`s textview change cause resize the tableview`s cell
self.tableView.estimatedRowHeight = 50.0;

quindi, combinando questo articolo soluzione in Swift  e alcuni pensieri sporchi Ho messo nella mia cella una proprietà, chiamata

@property (nonatomic, strong) UITableView *hostTableView;

e in cella-s -(void) textViewDidChange:(UITextView *)textView

 CGFloat currentTextViewHeight = _textContainer.bounds.size.height;
CGFloat toConstant = ceilf([_textContainer sizeThatFits:CGSizeMake(_textContainer.frame.size.width, FLT_MAX)].height);
if (toConstant  >  currentTextViewHeight)
{
    [_hostTableView beginUpdates];
    [_hostTableView endUpdates];
}

quindi in viewController

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

textCell.hostTableView = self.tableView;

after height change


1
2018-02-12 11:38



Basta disabilitare l'animazione prima di chiamare beginUpdates e riattivalo dopo aver chiamato endUpdates.

[UIView setAnimationsEnabled:NO];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled:YES];

Sicuramente un hack ma funziona per ora. Ringraziamento al mio amico Beau che mi ha indicato Questo.


4
2018-03-11 23:51



Non trovo un modo per ottenerlo perché: Quando si attiva [tableView endUpdates], la tabella ricalcola contentSize e la reimposta. E questo causa la reimpostazione di contentOffset sul valore predefinito.

Questo comportamento è ereditato da UIScrollView e ho cercato di evitarlo tramite:

  • Sottoclasse UITableView e override setContentOffset: e setContentOffset:animated funzioni. Ma non hanno chiamato quando la visualizzazione della tabella cambia contentSize.
  • Sottoclasse UITableView, sovrascrittura setContentSize: funzione e impostazione contentOffset al vecchio valore, dopo l'aggiornamento della dimensione del contenuto, ma non funziona per me
  • usando KVO e impostando il vecchio valore per contentOffset subito dopo il reset, ma comunque ho questo problema animato
  • impostazione scrollEnabled su NO e scrollToTop su NO, ma non aiuta

Se qualcuno trova la soluzione per questo problema benvenuto. Forse possibile soluzione - disabilita l'autolayout: iOS: setContentSize sta causando il salto dell'intero frame UIScrollView

AGGIORNAMENTO: Trovo la soluzione: modifica diretta dell'altezza della cella, dimensione del contenuto e offset del contenuto: Funziona per me (la vista tabella è delegata di UITextView della cella)

- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat textHeight = [textView sizeThatFits:CGSizeMake(self.width, MAXFLOAT)].height;
    if (self.previousTextHeight != textHeight && self.previousTextHeight > 0) {
        CGFloat difference = textHeight - self.previousTextHeight;
        CGRect cellFrame = self.editedCell.frame;
        cellFrame.size.height += difference;
        self.editedCell.frame = cellFrame;
        self.contentSize = CGSizeMake(self.contentSize.width, self.contentSize.height + difference);
        self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y + difference);
    }
    self.editedNote.comments = textView.text;
}

0
2017-12-13 18:09