2017-03-22 2 views
4

Current SetupAnfangsverzögerung für eine Zelle mit einem UITextView

Ich habe eine benutzerdefinierte Zelle, von einem xib geladen, wo die meisten seines Raumes von UITextView bedeckt ist. Auch diese Zelle kann ein paar Textansichten haben. Und es gibt nur wenige Elemente (eine UIView + 2 UILabels) innerhalb dieser Zelle.

Das Problem

Ich habe versucht, all diese Ansichten zu entfernen und Verzögerung bleibt, selbst wenn ich nur eine Textview haben. Auch die Verzögerung tritt nur zum ersten Mal auf. Später, wenn ich nach unten scrolle und in eine andere Zelle mit einer Textansicht hineinlaufe, passiert die Verzögerung überhaupt nicht.

Zusätzliche Informationen

Die Sache mit dieser kundenspezifischen Zelle ist, dass ein Textview zu einem UIStackView hinzugefügt wird. Zu Beginn ist ein Stackview leer, weil ich (zur Entwicklungszeit) nicht weiß, wieviele Textviews da sein dürfen/sollen.

Ich bin mir bewusst, dass dies eine andere Sache ist, die Leistung beeinträchtigen kann, aber ich habe es gelöst (ich denke, so gut es geht), indem Sie überprüfen, wie viele Textansichten bereits in stackview arrangedSubviews-Array gefunden werden, und Basierend auf dieser Information füge ich einfach Ansichten hinzu oder verberge sie (anstatt jedes Mal eine benötigte Anzahl von Textansichten zu zerstören und neu zu erstellen).

Ich habe versucht, Instrumente zu verwenden, aber ich habe nicht bemerkt, dass irgendwelche meiner Klassen CPU-Zeit beanspruchen, sondern eher einige UIKit Methodenaufrufe, die vom Framework intern aufgerufen werden, sind die Ursache dafür ... Bei Bedarf Ich kann einen Screenshot posten, aber ich denke, das ist nicht relevant, weil diese das übliche System zu sein scheinen & Framework-Aufrufe. Plus ich teste auf iPad 2: D also vielleicht ist das eine Sache (ich muss eine App für langsame Geräte optimieren).

Trotzdem kann ich das irgendwie optimieren?

Die MyCell Klasse ist ziemlich einfach (Pseudocode):

class MyCell:UITableViewCell{ 

    func configure(data:SomeData){ 

     self.addOrHideViewsIfNeeded() 
    } 

    private func addOrHideViewsIfNeeded(){ 
     //here, I check if stackview.arrangedSubviews has, and how many subviews are there, and 
     //add/hide them appropriately, means if I have to add them, I load them from the nib, otherwise, I reuse views from by adding them/removing them from a pool. 
    } 
} 

Auch die Verzögerung ist mehr noticealbe in Debug-Version in vergleichen Version Version, der Sinn machen, aber es ist immer noch spürbar.

+0

Oh ja, Textansichten werden anfänglich von einer Feder geladen und verwenden System Schriftart statt benutzerdefinierte Schriftart. – Whirlwind

+0

Ich glaube nicht, dass dies auf 'UITextView' zurückzuführen ist. Aus meiner Erfahrung und aus dem, was online gelesen werden kann, hat "UIStackView", obwohl es wirklich praktisch ist, eine schlechte Leistung. Komplizierte AutoLayout-Regeln benötigen ebenfalls einige Zeit zur Berechnung. In unserer App hatten wir ~ 20 Komponenten in einer Zelle und viele Einschränkungen, und es gab sichtbare Verzögerung, sogar auf neueren Geräten. Wir haben das gelöst, indem wir auf manuelles Layout umgestellt haben - wir berechnen die Frames selbst in den Zellen 'layoutSubviews'. Obwohl mir klar ist, dass dies viele Änderungen in Ihrem Code bedeuten kann, ist es vielleicht einen Versuch wert. – Losiowaty

+0

@Losiowaty Nun, die Sache ist, ich habe verschiedene Arten von Zellen in meiner Tabellenansicht. Jede Zelle hat eine eigene Ansicht. Nur die Zelle mit einer Textansicht bleibt zum ersten Mal zurück. Aber wie gesagt, Verzögerungen kommt von Macs Festplatte, während auf Debugger angebracht. Wenn eine Anwendung nicht über das USB-Kabel angeschlossen ist, gibt es keine (sichtbare) Verzögerung. Aber ja, Stack View ist nicht so performant. – Whirlwind

Antwort

1

Ok das ist eine Skizze von meiner Idee Null die Vorbelastung in einem unsichtbaren aus Benutzerperspektive Tableview Reihe zu tun.

class MyCell : UITableViewCell { 
    static var initiallyPreloaded : Bool = false 

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
     super.init(style: style, reuseIdentifier: reuseIdentifier) 

     if !MyCell.initiallyPreloaded { 
//Do the initial preloading setup by adding UITextView to self.contentView 
      MyCell.initiallyPreloaded = true 
     } else { 
//Setup the regular cell content otherwise 
     } 
    } 
    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 
} 

class ViewController: UIViewController , UITableViewDelegate { 
    func tableView(_ tableView: UITableView, 
        cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 
     var cell: MyCell? = tableView.dequeueReusableCell(withIdentifier: "myCellIdentifier") as! MyCell? 
     if cell == nil { 
      cell = MyCell(style: .default, reuseIdentifier: "myCellIdentifier") 
     } 
     if indexPath.row == 0 { 
//Display the initial cell in unnoticeable to user way (start with hidden/alpha zero) 
//For this zero-th row the initial preloading should happen 
     } 
     return cell! 
    } 
} 
+0

Ich musste nur "UITextView" bei der Initialisierung einer Zelle hinzufügen, anstatt dies nach der Initialisierung der Zelle zu tun. Ich musste dies auch in 'watchFromNib()' tun, weil ich auf Zellen-Outlets zugreife (die Textansicht wird nicht tatsächlich zur 'contentView' hinzugefügt, sondern eher zur stackview, wie ich in meiner Frage erwähnt habe). So wurden keine unsichtbaren Zellen benötigt. Wie auch immer, du hast mir geholfen, eine Lösung für das Problem zu finden. – Whirlwind

+0

Freut mich zu hören. In meinem Fall habe ich eine unsichtbare Animation gestartet, die normalerweise beim ersten Auftritt nicht funktionieren würde. Und richtig 'wakeFromNib()' ist ein Weg zu gehen, wenn Sie Interface Builder verwenden. –

2

Möglicherweise müssen Sie überprüfen, ob Sie die Zellen erneut verwenden oder nicht.

Sie können es wieder verwenden, wie unten:

-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NAIndexPath *) indexPath{ 

static NSString *cellIdentifier = @"Mycell"; 

cell = [tableView dequeueCellWithIdentifier:cellIdentifier]; 

if(cell == nil) 
    cell = [[MyCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: cellIdentifier]; 
} 
+0

Ich habe nibs registriert, indem ich das Tableview-Register (_ nib: UINib ?, forCellReuseIdentifier Bezeichner: String) in meinem 'viewDidLoad()' verwende. Außerdem habe ich einen Haltepunkt in der 'cellForRowAt'-Delegate-Methode gesetzt, und Zelle ist nicht Null, sondern wurde einfach aus der Warteschlange entfernt. Die Sache ist, dass die Verzögerung nur passiert, wenn ich auf Debugger bin. Ich habe mich geirrt und es gibt keine Verzögerung, wenn ich eine App auf einem tatsächlichen Gerät im Veröffentlichungsmodus starte, ohne sie an einen Debuger anzuhängen. Aber Sie haben meine Aufzählung, weil Ihre Antwort im Allgemeinen hilfreich sein könnte. – Whirlwind

Verwandte Themen