22 Stimmen

Was ist der beste Weg, die Farbe/die Ansicht des Offenlegungspfeil-Accessoire-Ansicht in einer Tabellenansichtszelle in iOS zu ändern?

Ich muss die Farbe des disclosureIndicatorView-Zubehörs in einer UITableViewCell ändern. Ich denke, es gibt zwei Möglichkeiten, um dies zu erreichen, aber ich kann nicht herausfinden, welche optimal ist. Hier ist also, was ich tun kann.

Es gibt eine Eigenschaft von UITableViewCell - accessoryView. Also kann ich setAccessoryView:(UIView *)view verwenden und view als das UIImageView übergeben, das das gewünschte Bild enthält.

Ich habe eine Hilfsklasse geschrieben, die die Inhaltsansicht (Dinge wie Hintergrundfarbe, Hinzufügen anderer Dinge usw.) für meine Zelle erstellt, und ich füge diese Inhaltsansicht der Zelle in UITableViewDelegate hinzu. Die andere Option besteht darin, ein UIImage zu zeichnen, indem die drawRect-Methode der Hilfsklasse CustomContentView überschrieben wird.

Bei Option 1 - kann ich die Dinge auf die Art und Weise von Apple erledigen. Einfach die Ansicht geben und sie erledigen den Rest. Aber ich vermute, dass das Hinzufügen eines neuen UIView-Objekts zu jeder Zeile sich als eine schwere Objektzuweisung erweisen könnte und die Bildrate verringert. Im Vergleich zu nur einem UIImage-Objekt in meiner contentView. Ich glaube, UIImage ist leichter als UIView.

Bitte werft etwas Licht darauf, Leute, und helft mir, mich zu entscheiden.

0 Stimmen

Sicherlich wünscht man sich, dass man das UIImageView einfach auf alle Zeilen teilen könnte.

0 Stimmen

Siehe eine Bibliothek. Ändern Sie ganz einfach die Farben aller Arten von accessoryType. MSCellAccessoryView

0 Stimmen

Alte Frage, aber bisher noch keine zufriedenstellende Antwort erhalten. Hier ist, was Sie wirklich gefragt haben: stackoverflow.com/a/35427599/378024

4voto

amrox Punkte 6157

Aber ich nehme an, das Hinzufügen eines neuen UIView-Objekts zu jeder Zeile könnte sich als eine schwere Objekthallokation erweisen und die Bildrate verringern, im Vergleich zu nur einem UIImage-Objekt in meinem contentView. Ich glaube, UIImage ist leichter als UIView.

Das direkte Zeichnen eines Bildes wird fast sicherlich eine bessere Leistung haben als das Hinzufügen einer Subansicht. Sie müssen herausfinden, ob diese zusätzliche Leistung erforderlich ist. Ich habe einige Accessory-Ansichten für benutzerdefinierte Offenbarungszeiger auf grundlegenden Zellen verwendet und die Leistung war in Ordnung. Wenn Sie jedoch bereits benutzerdefiniertes Zeichnen für den Inhaltsbereich durchführen, könnte es nicht so schwierig sein, die Accessory-Ansicht auch zu erstellen.

2voto

EeKay Punkte 59

Die Lösung von benzado funktioniert gut, aber sie zeigte einen schwarzen Hintergrund. In der UIView-Klasse, die Sie einrichten (die, deren drawRect-Funktion Sie in seinem Code platziert haben), muss die folgende initWithFrame-Implementierung haben, damit das Disclosure-Zeichnen einen transparenten Hintergrund hat:

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        [self setBackgroundColor:[UIColor clearColor]];
        // Initialisierungscode.
    }
    return self;
}

Natürlich können Sie dies auf die gewünschte Farbe einstellen...

1voto

ymerej Punkte 61

Während galambalazs' Antwort funktioniert, sollte darauf hingewiesen werden, dass es sich hierbei um eine Art Hack handelt, da es auf Apple's private Implementierung des Disclosure Indikators indirekt zugreift und diese aktualisiert. Im besten Fall könnte es in zukünftigen iOS-Versionen nicht mehr funktionieren und im schlimmsten Fall zur Ablehnung im App Store führen. Das Setzen des accessoryView ist immer noch die genehmigte Methode, bis Apple eine Eigenschaft freigibt, um die Farbe direkt zu setzen.

Unabhängig davon, hier ist die Swift-Implementierung seiner Antwort für diejenigen, die sie möchten:

Hinweis: cell.disclosureIndicatorColor muss nach dem Setzen von cell.accessoryType = .DisclosureIndicator gesetzt werden, damit die disclosureIndicator-Schaltfläche in den Subansichten der Zelle verfügbar ist:

extension UITableViewCell {

    public var disclosureIndicatorColor: UIColor? {
        get {
            return arrowButton?.tintColor
        }
        set {
            var image = arrowButton?.backgroundImageForState(.Normal)
            image = image?.imageWithRenderingMode(.AlwaysTemplate)
            arrowButton?.tintColor = newValue
            arrowButton?.setBackgroundImage(image, forState: .Normal)
        }
    }

    public func updateDisclosureIndicatorColorToTintColor() {
        self.disclosureIndicatorColor = self.window?.tintColor
    }

    private var arrowButton: UIButton? {
        var buttonView: UIButton?
        self.subviews.forEach { (view) in
            if view is UIButton {
                buttonView = view as? UIButton
                return
            }
        }
        return buttonView
    }
}

0 Stimmen

Der Zugriff auf die Ansichtshierarchie wurde von Apple noch nie verboten. Es sind in der Regel private APIs (Methoden, Eigenschaften oder Klassen, die nicht in der Dokumentation aufgeführt sind), die Probleme verursachen.

0 Stimmen

Das ist nicht nur der Zugriff auf die Ansichtshierarchie, sondern auch das indirekte Abrufen einer privaten UIButton-Eigenschaft über die Hierarchie und deren Änderung.

1voto

Alex Chase Punkte 790

In iOS 13+ wird der Offenbarungsindikator über ein nicht-vorlagenbasiertes UIImage festgelegt, das durch die Dunkelmoduspräferenz des Benutzers bestimmt wird. Da das Bild nicht-vorlagebasiert ist, respektiert es nicht die tintColor-Eigenschaft der Zelle. Mit anderen Worten, die Dunkelmoduspräferenz hat oberste Priorität. Wenn Sie den vom iOS abgeleiteten Offenbarungsindikator nicht verwenden möchten, müssen Sie ein benutzerdefiniertes Bild verwenden.

0voto

iPhoneDev Punkte 11

Als Beitrag zur Lösung von @benzado habe ich seinen Code wie folgt swiftifiziert:

override func drawRect(rect: CGRect) {

  super.drawRect(rect)

  let context = UIGraphicsGetCurrentContext();

  let right_margin : CGFloat = 15.0
  let length : CGFloat = 4.5;

  // (x,y) is the tip of the arrow
  let x = CGRectGetMaxX(self.bounds) - right_margin;
  let y = CGRectGetMidY(self.bounds);

  CGContextMoveToPoint(context, x - length, y - length);
  CGContextAddLineToPoint(context, x, y);
  CGContextAddLineToPoint(context, x - length, y + length);
  CGContextSetLineCap(context, .Round);
  CGContextSetLineJoin(context, .Miter);
  CGContextSetLineWidth(context, 2.5);

  if (self.highlighted)
  {
    CGContextSetStrokeColorWithColor(context, UIColor.appColorSelected().CGColor);
  }
  else
  {
    CGContextSetStrokeColorWithColor(context, UIColor.appColor().CGColor);
  }

  CGContextStrokePath(context);
}

Mit einer Änderung der App-Farbe wird ein Aufruf von setNeedsDisplay() auf der UITableCellView die Farbe aktualisieren. Ich möchte den Einsatz von UIImage-Objekten in Zellansichten vermeiden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X