25 Stimmen

Wie können Sie Interface Builder dazu bringen, die intrinsische Inhaltsgröße einer benutzerdefinierten Ansicht im einschränkungsbasierten Layout zu berücksichtigen?

Interface Builder in XCode 4.5 respektiert die intrinsicContentSize für einige Ansichten, z. B. NSButton, aber ich kann es nicht überzeugen, es auf meine eigenen benutzerdefinierten Unteransichten zu respektieren. Das führt dazu, dass IB zusätzliche Einschränkungen hinzufügt, die versuchen, das in IB gezeichnete Layout zu erzwingen, was dann dazu führt, dass die intrinsischen Größen nicht verwendet werden, wenn das Programm ausgeführt wird.

Nehmen wir zum Beispiel eine Schaltfläche, die in einem Fenster zentriert ist, und eine benutzerdefinierte Ansicht, die in einem Fenster zentriert ist

IB constraints for centered NSButton

IB constraints for centered NSView

Sie können sehen, dass die benutzerdefinierte Ansicht vier Einschränkungen erhält, vermutlich weil IB die intrinsicContentSize der Ansicht nicht kennt. Sie können ändern, welche zusätzlichen Beschränkungen hinzugefügt werden, z.B. können Sie erzwingen, dass sie stattdessen Breite und Höhe sind, aber Sie können sie nicht löschen.

Ich bin mit diesem jetzt durch die Suche und Löschen der zusätzlichen Einschränkungen in meinem awakeFromNib zu bewältigen, aber es muss ein besserer Weg, dies zu tun sein.

35voto

ravron Punkte 10753

Legen Sie im Interface Builder eine Platzhaltergröße für den Inhalt fest - eine "Schätzung", wenn Sie so wollen.

  1. Wählen Sie Ihre benutzerdefinierte Ansicht.
  2. Den Größeninspektor anzeigen ( Shift5 ).
  3. Ändern Sie das Dropdown-Menü "Intrinsische Größe" von "Standard (Systemdefiniert)" in "Platzhalter".
  4. Geben Sie vernünftige Schätzungen für die Laufzeitbreite und -höhe Ihrer Ansicht ein.

Diese Einschränkungen werden zur Kompilierzeit entfernt, was bedeutet, dass sie keine Auswirkungen auf die laufende Anwendung haben, und die Layout-Engine wird zur Laufzeit entsprechende Einschränkungen hinzufügen, um die intrinsicContentSize .

15voto

Fattie Punkte 34702

Wie man das wirklich macht, 2019

import UIKit

@IBDesignable class TagPerson: ShadowRoundedImageView {

    override var intrinsicContentSize: CGSize {
        var s = super.intrinsicContentSize
        s.height = 40
        s.width = 40
        return s
    }

    override func prepareForInterfaceBuilder() {
        invalidateIntrinsicContentSize()
    }

}

Es gibt jedoch ein Problem. Xcode ist fehlerhaft. Sie können es manchmal zurücksetzen, indem:

Die oben genannten Maßnahmen funktionieren natürlich zur Laufzeit einwandfrei. Aber es zufällig nicht in Interface Builder (auch mit 11+) zu arbeiten.

Um den Zyklus zu starten, versuchen Sie

  1. Das übliche 'Alle Ansichten aktualisieren'

  2. Fügen Sie eine sinnlose Einschränkung zu einer Ihrer intrinsischen Größenansichten hinzu und löschen Sie sie. (Ich habe bemerkt, wenn Sie eine Reihe von ihnen haben, tun dies zu einem ist in der Regel genug, um Xcode Zyklus zu machen, dann werden sie alle arbeiten.)

  3. Und schließlich:

Xcode hat eine "Platzhalter für intrinsische Größe" Funktion.

enter image description here

Wählen Sie eines oder mehrere Ihrer Elemente mit intrinsischer Größe aus. Schalten Sie das bizarre Platzhalter-Ding ein paar Mal hin und her. Oft wird dadurch ein Zyklus ausgelöst und die Ansicht funktioniert dann korrekt.

Schlimmstenfalls kann ein Neustart von Xcode mit dem üblichen Clean-Everything manchmal dazu führen, dass es funktioniert.

2voto

Mariam K. Punkte 590

Ok, hier geht es darum, dass Xcode die intrinsicContentSize Ihrer benutzerdefinierten Ansicht in IB.

Dies kann erreicht werden, indem ein Platzhalteransicht innerhalb Ihrer benutzerdefinierten Ansicht in IB mit einer festen Breite und Höhe (Sie können sie auch horizontal und vertikal zentrieren)

enter image description here

Wählen Sie dann Ihre benutzerdefinierte Ansicht und tippen Sie auf "Größe an Inhalt anpassen" aus dem Menü Bearbeiten in IB. Zu diesem Zeitpunkt können alle zusätzlichen Größenbeschränkungen gelöscht werden, so dass nur die Positionierungsbeschränkungen übrig bleiben.

enter image description here

Auf diese Weise wird IB die Größe Ihrer benutzerdefinierten Ansicht an die Platzhalteransicht anpassen und Autolayout würde von der Überschreibung Ihrer Ansicht von - (CGSize)intrinsicContentSize zur Laufzeit, um die Größe Ihrer benutzerdefinierten Ansicht zu bestimmen.

Der letzte Schritt besteht darin, die Platzhalteransicht zu löschen, damit der Inhalt und die Größe Ihrer Ansicht korrekt angezeigt werden können:

   - (void)viewDidLoad
    {
        [super viewDidLoad];
        [_placeholderView removeFromSuperview];
    }

Ich weiß, dass dies ein Hack ist, aber ich hoffe, es hilft Ihnen.

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