UiTableView langsames bzw. hängendes Scrollen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • UiTableView langsames bzw. hängendes Scrollen

    Hey Leute,

    Folgendes:

    Ich habe einen UITableViewerController der ca. 7 Sections mit jeweils einer Cell hat. Desweiteren habe ich implementiert, dass wenn man auf die HeaderView toucht, die Sections auf - bzw. zuklappen.
    Dazu setze ich numberOfRows in der Section auf 0.

    Nun ist es aber so, dass wenn ich nach unten oder oben scrolle, einige Hänger gibt. Also es läuft nicht flüssig. Habe schon eigentich alles aus cellForRowAtIndexPath rausoptimiert, sodass ich dort nur nach den Text setze. Siehe hier:

    Quellcode

    1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    2. {
    3. UITableViewCell *cell;
    4. if(indexPath.section == 0)
    5. {
    6. cell = (ProductTitleCell *)[tableView dequeueReusableCellWithIdentifier:@"ProductTitleCellID" forIndexPath:indexPath];
    7. if(!cell)
    8. {
    9. cell = (ProductTitleCell *)[[NSBundle mainBundle] loadNibNamed:@"ProductTitleCell" owner:self options:0][0];
    10. cell.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.65];
    11. }
    12. ((ProductTitleCell *)cell).productTitle.text = [productInfos objectForKey:@"prname"];
    13. ((ProductTitleCell *)cell).productSubtitle.text = [productInfos objectForKey:@"prtitle"];
    14. ((ProductTitleCell *)cell).productMerkmale.text = [productInfos objectForKey:@"merkmale"];
    15. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    16. GDataXMLElement *prodImage = [_product elementsForName:@"product_image"].firstObject;
    17. NSString *imgString = prodImage.stringValue;
    18. UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imgString]]];
    19. dispatch_async(dispatch_get_main_queue(), ^{
    20. if(img)
    21. {
    22. ((ProductTitleCell *)cell).productImage.image = img;
    23. }
    24. });
    25. });
    26. }
    27. else if(indexPath.section == 1)
    28. {
    29. cell = (TextViewCell *)[tableView dequeueReusableCellWithIdentifier:@"TextViewCellID" forIndexPath:indexPath];
    30. if(!cell)
    31. {
    32. cell = (ProductTitleCell *)[[NSBundle mainBundle] loadNibNamed:@"TextViewCell" owner:self options:0][0];
    33. cell.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.65];
    34. }
    35. ((TextViewCell *)cell).contentLabel.text = productDescription;
    36. [((TextViewCell *) cell).contentLabel sizeToFit];
    37. }
    38. else if(indexPath.section > 1 && indexPath.section < merkmaleHeader.count + 2)
    39. {
    40. cell = (TextViewCell *)[tableView dequeueReusableCellWithIdentifier:@"TextViewCellID" forIndexPath:indexPath];
    41. if(!cell)
    42. {
    43. cell = (ProductTitleCell *)[[NSBundle mainBundle] loadNibNamed:@"TextViewCell" owner:self options:0][0];
    44. cell.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.65];
    45. }
    46. ((TextViewCell *)cell).contentLabel.attributedText = merkmaleContent[indexPath.section - 2];
    47. [((TextViewCell *) cell).contentLabel sizeToFit];
    48. }
    49. return cell;
    50. }
    Alles anzeigen


    Findet dort jemand (Bis auf das Bild laden) einen performancefressenden Fehler?

    Da die HeaderView auch eine UIVisualView bzw. unter iOS 7 eine UIView mit Semitransparenz und 2 Label hat, habe ich diese auch schon gecached. Läuft aber immernoch nicht.

    Vielleicht hat es ja etwas damit zu tun, dass die Cells dynamische Größen haben, also abhängig vom Content. Das habe ich gelöst indem ich einfach

    Quellcode

    1. - (CGFloat) tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
    2. {
    3. return 200;
    4. }


    gesetzt habe. Da wäre die Frage, warum funktioniert das?? Unter iOS 7 funktionierts nicht. Da werden die Cells immer mit 44 Höhe erstellt. Unter iOS 8 nimmt er die dynamische Größe der Cell.

    Fragen über Fragen... Wäre dankbar für Tipps und Hilfe

    Danke! :)
    Every language has an optimization operator. In ObjC that operator is ‘//’.

    golbros.de
  • gritsch schrieb:

    warum ratest du?
    wirf doch einfach die entsprechenden tools an.

    wie sagst du der tableview die genaue (nicht nur die geschätze) höhe der rows?


    Wollte eure Meinungen hören. :) Bzw. Tipps.

    Das sag ich ihr eben gar nicht. Deswegen wunderts mich, dass es so funktioniert. (Zumindest unter iOS 8).
    Every language has an optimization operator. In ObjC that operator is ‘//’.

    golbros.de
  • Fortrackz schrieb:

    gritsch schrieb:

    warum ratest du?
    wirf doch einfach die entsprechenden tools an.

    wie sagst du der tableview die genaue (nicht nur die geschätze) höhe der rows?


    Wollte eure Meinungen hören. :) Bzw. Tipps.

    Das sag ich ihr eben gar nicht. Deswegen wunderts mich, dass es so funktioniert. (Zumindest unter iOS 8).


    ja dann wird er sich eben alle cells holen. vielleicht steht in der doku dazu was (ich hab sie nicht gelesen).
    oder hau einfach ein NSLog rein und lade die app. wenn er dann nur 20 (die sichtbaren) logeinträge zeigt dann sind die wohl langsam (solltest du messen), wenn er aber 1.000 (alle deine rows) anzeigt dann weist du was sache ist!
  • (Große) Tableviews mit flexiblen Zellhöhen führen extrem schnell zu langsamen Scrollen.

    Ein weiteres Performance-Leak ist natürlich die Art, wie du die Bilddaten lädst. Du verstopfst die globale Queue (Warum verwendest du nicht sendAsynchronousRequest:queue:completionHandler:?). Außerdem solltest du dir mal das Caching anschauen.
    „Meine Komplikation hatte eine Komplikation.“
  • so, jetzt habe ich DEINE arbeit gemacht un die doku zur besagten methode angeschaut:

    Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time.


    so langsam frage ich mich echt warum man die verdammte doku nicht liest?
    es wird die zeit kommen, da werden solche threads nur noch mit RTFM beantwortet werden...
  • kmr schrieb:

    gritsch schrieb:


    es wird die zeit kommen, da werden solche threads nur noch mit RTFM beantwortet werden...


    Warum kümmerst Du Dich denn um solche Postings? Wenn Dir die Schöpfungshöhe der Frage nicht passt, ignoriere die doch einfach statt pampig zu werden. ;)


    weil ich davon ausgegangen bin dass er das naheliegendste (doku lesen) bereits getan hat. (ich hab ja auch noch andere zielführende ansätze angegeben...)
  • gritsch schrieb:

    weil ich davon ausgegangen bin dass er das naheliegendste (doku lesen) bereits getan hat. (ich hab ja auch noch andere zielführende ansätze angegeben...)


    Bei Doku lesen bin ich immer nachsichtig. Ich selber übersehe immer so viel in der Doku …

    Ärgerglicher finde ich die Kandidaten, deren Grundlagenwissen aus dem Herunterladen von Xcode aus dem App Store besteht. Da muss ich dann immer schnell drüber weglesen.
  • kmr schrieb:

    gritsch schrieb:

    weil ich davon ausgegangen bin dass er das naheliegendste (doku lesen) bereits getan hat. (ich hab ja auch noch andere zielführende ansätze angegeben...)


    Bei Doku lesen bin ich immer nachsichtig. Ich selber übersehe immer so viel in der Doku …

    Ärgerglicher finde ich die Kandidaten, deren Grundlagenwissen aus dem Herunterladen von Xcode aus dem App Store besteht. Da muss ich dann immer schnell drüber weglesen.


    warum? dann weis man zumindest welchen stand sie haben.
    wenn man aber solche fragen liest, denkt man doch dass zumindest di doku gelesen wird zu den zwei fraglicehn methoden.
    das geht ja auch viel schneller als ins forum zu posten (in der not kann man es auch zweimal lesen oder sagen dass man die doku nicht ganz versteht, in dem genannten fall ist sie aber wohl eindeutig oder nicht?)
  • gritsch schrieb:

    kmr schrieb:

    gritsch schrieb:


    es wird die zeit kommen, da werden solche threads nur noch mit RTFM beantwortet werden...


    Warum kümmerst Du Dich denn um solche Postings? Wenn Dir die Schöpfungshöhe der Frage nicht passt, ignoriere die doch einfach statt pampig zu werden. ;)


    weil ich davon ausgegangen bin dass er das naheliegendste (doku lesen) bereits getan hat. (ich hab ja auch noch andere zielführende ansätze angegeben...)


    Die Doku zu lesen, bringt mich meist nicht weiter. In dem Fall okay, ja.
    Aber sonst lese ich die und hab am Ende dann doch nicht das was ich will. Da frage ich lieber in einem Forum, um dann vielleicht schon gute bzw. logische Ansätze zu bekommen die auch schon angewendet wurden.

    Das hier einen Thread zu erstellen gleich Hohn und Spott zu ernten bedeutet wusste ich nicht.
    Every language has an optimization operator. In ObjC that operator is ‘//’.

    golbros.de
  • Fortrackz schrieb:

    gritsch schrieb:

    kmr schrieb:

    gritsch schrieb:


    es wird die zeit kommen, da werden solche threads nur noch mit RTFM beantwortet werden...


    Warum kümmerst Du Dich denn um solche Postings? Wenn Dir die Schöpfungshöhe der Frage nicht passt, ignoriere die doch einfach statt pampig zu werden. ;)


    weil ich davon ausgegangen bin dass er das naheliegendste (doku lesen) bereits getan hat. (ich hab ja auch noch andere zielführende ansätze angegeben...)


    Die Doku zu lesen, bringt mich meist nicht weiter. In dem Fall okay, ja.
    Aber sonst lese ich die und hab am Ende dann doch nicht das was ich will. Da frage ich lieber in einem Forum, um dann vielleicht schon gute bzw. logische Ansätze zu bekommen die auch schon angewendet wurden.

    Das hier einen Thread zu erstellen gleich Hohn und Spott zu ernten bedeutet wusste ich nicht.


    aber auch diese aussage zeugt von faulheit (und du hast auch nicht hohn und spott geernet nur ein bisschen meine verärgerung).
    du lässt also lieber andere ein problem lösen welches gar nciht existieren würde wenn du die doku lesen würdest? hättest du das getan und trotzdem nicht weitergekommen wäre der weg ins forum ja noch offen gestanden. aber sich auf die hilfsbereitschaft anderer zu verlassen und selbst nicht vorher 3 sätze lesen finde ich schon ein bisschen dreist.
  • Fortrackz schrieb:

    Das hier einen Thread zu erstellen gleich Hohn und Spott zu ernten bedeutet wusste ich nicht.

    Diese Verallgemeinerung ist falsch. Du bist doch auch schon länger dabei, und solltest das auch wissen. Abgesehen davon hast du in diesem Thread auch jede Menge Hinweise erhalten, wo du ansetzen kannst.

    Wenn man sich im Internet bewegt, muss man sich (leider) ein dickes Fell zulegen. ;)
    „Meine Komplikation hatte eine Komplikation.“
  • Ich hänge über diesen Problem schon einige Tage. Deswegen auch mein Post hier. Ist ja nicht so, dass ich das Problem habe und dann gleich hier her renne.
    Außerdem komme ich ja nicht mit:

    Hallo, ich habe "int x = 1". Wie programmiere ich jetzt einen 3D Shooter.

    Ich habe ein konkretes Problem, habe versucht es schon einzugrenzen und bin immernoch nicht zufrieden.
    Ich fühle mich auch in keinster weise angegriffen oder so. @macmoonshine Ein dickes Fell ist ja voraussetzung. :D

    Insgeheim hoffte ich nur auf ein interessanten Post von Amin, der mir das super schildert.

    Sei's drum. Die Ansätze sind gut, habe/werde ich umsetzen.

    Zu meinem Problem:

    Habe nun die konkreten Höhen der Cells berechnet und gebe diese nun auch in heightForRowAtIndexPath zurück. Läuft nun auch unter iOS 7.
    Nur auf meinem iPhone 6+ läuft immernoch nicht ganz rund. Es gibt immernoch kleine Ruckler.

    Ein Grund war, dass ich in einer geistlosen Minute in numberOfRowsInSection eine for - Schleife implementiert habe, die ein Array für die Rowanzahl durchläuft anstatt einfach rowNumbers[section] zu schreiben.
    Wie gesagt Headerviews habe ich gecached. Es sind nur 7 Section also insgesamt 7 Rows.

    Allociere ich vielleicht die Cells komplett falsch? Werde da nochmal nachlesen..

    Mögliche Ursachen, sind ja viele Subviews einer Cell (Trifft hier nicht zu. Nur ein UILabel pro Cell, in der ersten eine ImageView und 2 Labels).
    Semitransparenz -> Habe ich tatsächlich. Der Cell Background ist weiß mit 0.65 alpha. Habe dies aber auch schon auf komplett weiß umgestellt.

    Edit:
    Also habe nun Transparenz weggelassen. Habe zusätzlich bei der Headerview die oberen Ecken abgerundet, dies hab ich nun auch wieder rückgängig gemacht.
    Die Headerview ist nun auch keine UIVisualView mehr. (8 Stück sind wohl doch heavy).

    Jetzt läuft es eigentlich gut.

    Every language has an optimization operator. In ObjC that operator is ‘//’.

    golbros.de
  • Also habe nun endlich den Übeltäter gefunden. Nun scrollt es wie wohnt.

    Und zwar habe ich der Headerview einen Shadow gegeben und

    Quellcode

    1. headerViewer.layer.shadowOpacity = 0.3;
    hat das hängende Scrollen verursacht.

    Ich hatte gelesen, dass Transparenz ein Problem sei, aber dachte dauernd nur an backgroundColor..

    Naja danke an alle!
    Every language has an optimization operator. In ObjC that operator is ‘//’.

    golbros.de