alle Subviews im ContentView einer UICollectionViewCell skalieren

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

  • alle Subviews im ContentView einer UICollectionViewCell skalieren

    Hi,

    ich erstelle zur Laufzeit ein Array mit 12 UIViews, jeweils mit einer Größe von 94x94 px.
    In jeder dieser 12 Views liegen 50 UILabel (Font Size 7).

    Diese Views bereite ich aus Performancegründen beim Applikationsstart vor und lege sie in "cellForItemAtIndexPath" in die entsprechenden CollectionView Zellen.
    Den Zellen habe ich in "collectionview() Layout() sizeForItemAtIndexPath" eine feste Größe gegeben, so dass im Hochformat 3 Zellen nebeneinander liegen und im Querformat 4 Zellen.
    Im Hochformat ist der Frame der Zelle entsprechend genau 94x94 px groß. Im Querformat werden sie je nach iPhone Version etwas größer.

    Ich versuche zu erreichen:
    - das die Zellen und Subviews (incl. Font Size) im Querformat skaliert werden
    - das die Zellen im "iPad Storyboard" entsprechend für Hoch- und Querformat per Code skaliert werden
    - das alle Abstände zwischen den Zellen und dem Rand gleich groß sind

    Das bekomme ich nicht hin. Ich kämpfe seit Tagen mit UIView. ClipToBounds, AutoResiszingMasks, Constraints & Co.....
    Bisher keine nennenswerten Erfolge.

    Im Screenshot unten habe ich mal Border für die "inneren Views" im Cell.ContentView (rot) und den Cell.frame im Querformat (gelb) zeichnen lassen.
    Wie kann ich die inneren Views samt Inhalt so skalieren, das die Größe genau den Cell Frames entspricht?
  • Wenn Du Autosizing verwendest, solltest Du die Breite und Höhe des inneren Views flexibel setzen und dessen Frame auf die Bounds des äußeren. Also ungefähr so:

    Quellcode

    1. UIView *theView = ...;
    2. theView.frame = theCell.contentView.bounds;
    3. theView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    4. [theCell.contentView addSubview:theView];
    „Meine Komplikation hatte eine Komplikation.“
  • JensW_2000 schrieb:

    Die 50 UILabel im inneren werden aber noch nicht skaliert.

    Das wird richtig schwierig, da Cocoa Touch Deinen View nicht skaliert sondern nur dessen Abmessungen vergrößert. Die einfachste Lösung wäre, die Buchstaben so zu lassen, wie sie sind und den inneren View nur zu zentrieren. Alternativ kannst Du auch für den inneren View eine eigene Klasse verwenden, in der Du die Methode layoutSubviews überschreibst. Darin kannst Du dann jedes Label neu ausrichten.

    Übrigens liegt Dein Perfomance-Leak an diesen vielen Labels. Es ist wahrscheinlich wesentlich performanter, die Zahlen direkt zu zeichnen. Dann brauchst Du auch Deine Views nicht zu cachen.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:


    Übrigens liegt Dein Perfomance-Leak an diesen vielen Labels. Es ist wahrscheinlich wesentlich performanter, die Zahlen direkt zu zeichnen. Dann brauchst Du auch Deine Views nicht zu cachen.


    Das habe ich auch immer geglaubt, ist aber nicht so.
    Wir hatten das Thema vor einiger Zeit schon einmal.

    Mein CollectionView liegt auf einem UIPageController.
    Wenn ich die Zellen nicht cache, sondern direkt in "MyCellClass.initWithFrame" fülle, dann hängt der PageController 2-4 Sekunden beim swipen durch die Seiten.
    Dabei spielt es keine Rolle, ob ich die 600 "Texte" im CollectionView mit "UILabel.lloc.initWithFrame" erstelle oder via "CGRectMake" + "NSString.drawInRect" direkt auf dem contentView "male".
    Ich denke, das Finden per Position bei initWithFrame bzw. CGRectMake ist die eigentliche Performancebremse.

    Aber egal.
    Ich probiere das trotzdem gerne noch einmal aus.
    Durch das neu hinzugekommene "Skalierungsszenario" sollte ich mit aString.drawInRect deutlich besser wegkommen.
    Ich kann ja weiterhin auf gecachten "inneren Views" malen..
  • Habe es jetzt wie folgt umgebaut..

    In der CollectionDataSource erstelle ich mir beim Laden der CollectionView mit Hilfe der NSDateComponents vorbereite Kalenderdaten für das ganze Jahr.
    Dann habe ich die Methode drawRect der benutzerdef. Zellen-Klasse überschrieben und zeichne dort mit "TagXinWocheY".stringValue.drawInRect(...) den Kalender in den CG Context der Zelle.

    Die positiven Effekte sind:
    - der Aufbau der UI ist auf diesem Wege wirklich "rattenschnell"
    - da ich nur noch eine grafische Repräsentation der Zelle habe (ohne SubViews), skaliert der komplette Inhalt perfekt mit.

    Das ist auf alle Fälle die Lösung, die ich anstrebe.

    Allerdings gibt es ein riesiges Problem.
    Durch das Überschreiben von "drawRect" zeichne ich den Kalender direkt im CGContext der Zelle und nicht wie von Apple vorgesehen im Context des contentViews.
    Das hat den Effekt, dass mein "gezeichneter Kalender" auf "Layer 0" liegt und vom contentView (sogar von den backgroundViews) "überlagert" wird.
    Darum kann ich keinen weißen Hintergrund für die Zelle setzen oder einen Background Layer mit runden Ecken.
    Egal was in den vorgesehenen Views eingefügt wird... Alles überlagert den Kalender und kann daher nur transparent sein.

    Ich müsste also "drawRect" des ContentViews überschreiben. Aber da komme ich nicht heran.

    In der Doku zur CollectionViewCell bzw. zum UICollectionReusableView steht leider nicht sehr viel dazu.
    Vermutlich bleibt aus Ausweg nur eine zusätzliche UIView, deren "drawRect" ich stattdessen überschreibe und die ich als subView auf den contentView der Zelle lege...
  • macmoonshine schrieb:

    Warum so kompliziert? Du musst einfach nur eine eigene View-Klasse schreiben, in der Du drawRect: überschreibst. Davon erzeugst Du pro Zelle einen View, den Du (wie oben) in den Contentview der Zelle legst


    Sag ich doch ;)
    "Vermutlich bleibt aus Ausweg nur eine zusätzliche UIView, deren "drawRect" ich stattdessen überschreibe und die ich als subView auf den contentView der Zelle lege..."

    Danke.
    Du hast mich genau in die richtige Richtung geschupst...