web-dev-qa-db-de.com

Wie erzwinge ich das erneute Zeichnen (drawRect) einer Unteransicht, wenn sich die Abmessungen ändern?

Ich habe eine UIView, die eine Reihe von Unterklassen von UIView enthält. Die Unterklasse hat drawRect: überschrieben und contentMode = UIViewContentModeRedraw gesetzt.

Wenn der Benutzer den übergeordneten Container drückt und streckt, wird der child views gedrückt und gedehnt. Wenn sich die Form ändert, möchte ich, dass drawRect wiederholt aufgerufen wird, um den Inhalt des child views zu ändern. Bisher war ich erfolglos. Was ist der richtige Weg, um dies zu tun?

Prost,

Doug

23
dugla

In Cocoa rufen Sie selten (wenn überhaupt) drawRect an. Sie markieren nur die Region oder Ansicht, die aktualisiert werden muss, und es wird für das Neuzeichnen geplant. Auf diese Weise können Wiederherstellungen für mehrere Ungültigerklärungen zusammengefasst werden. 

Für Cocoa Touch möchten Sie entweder [viewNeedsDisplay anzeigen] oder SetNeedsDisplayinRect: (CGRect)

58
Adam Wright

Sie müssen [view setNeedsLayout] aufrufen. Dadurch sollten die Unteransichten einen drawRect: -Aufruf erhalten, wenn sich das Layout ändert. Ich habe das jedoch nicht getestet.

3
Pascal

Diese Lösung ist etwas verrückt, macht aber logisch Sinn und hat ein tolles visuelles Ergebnis. Ich arbeite mit einer NSLayoutManager und ein paar NSTextContainers und lege den Text in zwei Spalten an. Da ich mehrere Textcontainer verwende (und nicht sicher bin, ob ich mehrere UITextView-Befehle haben möchte), überschreibe ich die draw(rect: CGRect)-Methode von MyDrawingView: UIView

Das Problem ist, dass die Verwendung von self.contentMode = .redraw immer noch zu einer geringfügigen Streckung bei der Rotation führt - signifikant genug, um ein Dealbreaker zu sein.

Ich habe bemerkt, dass die Einstellung contentMode = .left oder sogar contentMode = .scaleAspectFit in Bezug auf pixelgenaue Rotation nahe an dem liegt, was ich wollte. Aber offensichtlich bekam ich nicht den Ziehanruf, den ich brauchte.

Also habe ich layoutSubviews() überschrieben, die contentMode auf .scaleAspectFit umgestellt, super.layoutSubviews() genannt, und dann wieder zurückgeschaltet. : P

override func layoutSubviews() {
    self.contentMode = .scaleAspectFit

    super.layoutSubviews()
    self.contentMode = .redraw
}

Es ist perfekt.

0
Stan