Apple hat UIView
im Dokument ziemlich klar definiert, wie Unterklassen erstellt werden sollen .
Schauen Sie sich die Liste unten an, insbesondere werfen Sie einen Blick auf initWithFrame:
und layoutSubviews
. Ersteres dient zum Einrichten des Rahmens von Ihnen, UIView
während letzteres den Rahmen und das Layout seiner Unteransichten einrichten soll.
initWithFrame:
Denken Sie auch daran, dass dies nur aufgerufen wird, wenn Sie Ihre UIView
programmgesteuert instanziieren . Wenn Sie es aus einer NIB-Datei (oder einem Storyboard) laden, initWithCoder:
wird es verwendet. Da initWithCoder:
der Frame noch nicht berechnet wurde, können Sie den in Interface Builder eingerichteten Frame nicht ändern. Wie in dieser Antwort vorgeschlagen , können Sie anrufeninitWithFrame:
aus initWithCoder:
dem Rahmen , um der Einrichtung.
Wenn Sie Ihre UIView
Daten von einer Schreibfeder (oder einem Storyboard) laden , haben Sie außerdem die awakeFromNib
Möglichkeit, seit wann benutzerdefinierte Rahmen- und Layoutinitialisierungen durchzuführenawakeFromNib
Aufruf garantiert ist, dass jede Ansicht in der Hierarchie nicht archiviert und initialisiert wurde.
Aus dem Dokument von NSNibAwaking
(jetzt ersetzt durch das Dokument von awakeFromNib
):
Nachrichten an andere Objekte können sicher aus awakeFromNib gesendet werden. Zu diesem Zeitpunkt ist sichergestellt, dass alle Objekte nicht archiviert und initialisiert sind (obwohl dies natürlich nicht unbedingt aktiviert ist).
Es ist auch erwähnenswert, dass Sie mit Autolayout den Rahmen Ihrer Ansicht nicht explizit festlegen sollten. Stattdessen sollten Sie eine Reihe ausreichender Einschränkungen angeben, damit der Frame automatisch von der Layout-Engine berechnet wird.
Direkt aus der Dokumentation :
Methoden zum Überschreiben
Initialisierung
initWithFrame:
Es wird empfohlen, diese Methode zu implementieren. Sie können zusätzlich zu oder anstelle dieser Methode auch benutzerdefinierte Initialisierungsmethoden implementieren.
initWithCoder:
Implementieren Sie diese Methode, wenn Sie Ihre Ansicht aus einer Interface Builder-NIB-Datei laden und Ihre Ansicht eine benutzerdefinierte Initialisierung erfordert.
layerClass
Implementieren Sie diese Methode nur, wenn Ihre Ansicht eine andere Kernanimationsebene für den Hintergrundspeicher verwenden soll. Wenn Sie beispielsweise OpenGL ES zum Zeichnen verwenden, möchten Sie diese Methode überschreiben und die CAEAGLLayer-Klasse zurückgeben.
Zeichnen und Drucken
drawRect:
Implementieren Sie diese Methode, wenn Ihre Ansicht benutzerdefinierten Inhalt zeichnet. Wenn Ihre Ansicht keine benutzerdefinierten Zeichnungen ausführt, sollten Sie diese Methode nicht überschreiben.
drawRect:forViewPrintFormatter:
Implementieren Sie diese Methode nur, wenn Sie den Inhalt Ihrer Ansicht während des Druckvorgangs anders zeichnen möchten.
Einschränkungen
requiresConstraintBasedLayout
Implementieren Sie diese Klassenmethode, wenn für Ihre Ansichtsklasse Einschränkungen erforderlich sind, damit sie ordnungsgemäß funktionieren.
updateConstraints
Implementieren Sie diese Methode, wenn Ihre Ansicht benutzerdefinierte Einschränkungen zwischen Ihren Unteransichten erstellen muss.
alignmentRectForFrame:
, frameForAlignmentRect:
Implementieren Sie diese Methoden außer Kraft zu setzen , wie Sie Ihre Ansichten zu anderen Ansichten ausgerichtet sind.
Layout
sizeThatFits:
Implementieren Sie diese Methode, wenn Ihre Ansicht eine andere Standardgröße haben soll als normalerweise beim Ändern der Größe. Sie können diese Methode beispielsweise verwenden, um zu verhindern, dass Ihre Ansicht so weit verkleinert wird, dass Unteransichten nicht mehr korrekt angezeigt werden können.
layoutSubviews
Implementieren Sie diese Methode, wenn Sie eine genauere Kontrolle über das Layout Ihrer Unteransichten benötigen, als dies durch die Einschränkung oder das Verhalten bei der automatischen Größenänderung möglich ist.
didAddSubview:
, willRemoveSubview:
Implementieren diese Verfahren je nach Bedarf die Ergänzungen und Löschungen von Subviews zu verfolgen.
willMoveToSuperview:
, didMoveToSuperview
Implementieren diese Verfahren als notwendig , um die Bewegung der aktuellen Ansicht in der Ansichtshierarchie zu verfolgen.
willMoveToWindow:
, didMoveToWindow
Implementieren Sie diese Methoden als notwendig , um die Bewegung Ihrer Ansicht in ein anderes Fenster zu verfolgen.
Handhabung des Events:
touchesBegan:withEvent:
, touchesMoved:withEvent:
, touchesEnded:withEvent:
, touchesCancelled:withEvent:
Implementieren Sie diese Methoden , wenn Sie direkt Berührungsereignisse zu handhaben müssen. (Verwenden Sie für gestenbasierte Eingaben Gestenerkenner.)
gestureRecognizerShouldBegin:
Implementieren Sie diese Methode, wenn Ihre Ansicht Berührungsereignisse direkt verarbeitet und möglicherweise verhindern möchte, dass angehängte Gestenerkenner zusätzliche Aktionen auslösen.
Gabriele Petronella
quelle
layoutSubviews
?Dies kommt bei Google immer noch hoch an. Unten finden Sie ein aktualisiertes Beispiel für Swift.
Mit dieser
didLoad
Funktion können Sie Ihren gesamten benutzerdefinierten Initialisierungscode eingeben. Wie bereits erwähnt,didLoad
wird es aufgerufen, wenn eine Ansicht programmgesteuert über erstellt wirdinit(frame:)
oder wenn der XIB- Deserializer eine XIB- Vorlage über in Ihre Ansicht zusammenführtinit(coder:)
quelle
draw
Methode überschreiben ?Die Apple- Dokumentation enthält eine anständige Zusammenfassung, die im kostenlosen Stanford-Kurs bei iTunes ausführlich behandelt wird. Ich präsentiere meine TL; DR-Version hier:
Wenn Ihre Klasse hauptsächlich aus Unteransichten besteht, sind die
init
Methoden der richtige Ort, um sie zuzuweisen . Für Ansichten gibt es zwei verschiedeneinit
Methoden, die aufgerufen werden können, je nachdem, ob Ihre Ansicht über Code oder über eine Schreibfeder / ein Storyboard instanziiert wird. Ich schreibe meine eigenesetup
Methode und rufe sie dann sowohl von derinitWithFrame:
als auch von derinitWithCoder:
Methode auf.Wenn Sie benutzerdefinierte Zeichnungen erstellen, möchten Sie diese tatsächlich überschreiben
drawRect:
. Wenn Ihre benutzerdefinierte Ansicht jedoch hauptsächlich ein Container für Unteransichten ist, müssen Sie dies wahrscheinlich nicht tun.Überschreiben
layoutSubViews
Sie nur, wenn Sie beispielsweise eine Unteransicht hinzufügen oder entfernen möchten, je nachdem, ob Sie sich im Hoch- oder Querformat befinden. Andernfalls sollten Sie es in Ruhe lassen können.quelle
layoutSubViews
Es hat funktioniert.layoutSubviews
soll den Rahmen für untergeordnete Ansichten festlegen, nicht für die Ansicht selbst.Für
UIView
, ist der designierte Konstruktor der Regel ,initWithFrame:(CGRect)frame
und Sie sollten den Rahmen dort eingestellt (oder ininitWithCoder:
), möglicherweise nicht beachtet werden Rahmenwert übergeben. Sie können auch einen anderen Konstruktor angeben und den Rahmen dort festlegen.quelle
awakeFromNib