Cocoa: Existiert ein NSView mit Benutzerresize-Fähigkeit?

8

Ich möchte ein NSView, dessen Größe geändert werden kann, indem ich es wie ein NSWindow in der unteren rechten Ecke ziehe. Ich möchte in der Lage sein, dieses NSView in ein übergeordnetes NSView einzubetten. Gibt es eine solche Komponente in Cocoa oder einer ihrer Erweiterungen?

    
Max 10.10.2010, 06:00
quelle

2 Antworten

7

Wenn Sie mit Ihrer Frage spezifischer werden, kann ich mit der Antwort etwas konkreter werden. : -)

Es gibt nichts Vergleichbares, das ich kenne, aber es ist nicht so schwer zu erstellen. Die Entscheidung, die getroffen werden muss, lautet: "Wer handhabt das Zeichnen der Größenänderungsgriffe und das Ändern der Größe / Ziehen der Logik?"

Ansichten behandeln ihre eigenen

Wenn die benutzerdefinierbare Ansicht das Zeichnen der Griffe und das Reagieren auf die Größenänderungs- / Ziehaktionen selbst übernimmt, müssen Sie auswählen, ob die Griffe auf dem Inhalt der Ansicht oder "außen" gezeichnet werden sollen. Wenn Sie die Griffe "draußen" haben möchten, nimmt der "nutzbare Bereich" ab, da Ihr Inhalt so weit eingefügt werden muss, dass Sie die Größenänderungssteuerelemente zeichnen können, was die Zeichen- und Größenmesswerte erschweren kann. Wenn Sie die Griffe "über" dem Inhalt zeichnen, können Sie dieses Problem vermeiden.

Containeransicht behandelt alle Untersichten

Die Alternative besteht darin, eine "resizierbare Ansichtscontaineransicht" zu erstellen, die die Größenänderungsgriffe um die Unterperimeter zieht und die Ziehen- / Größenänderungslogik behandelt, indem sie die Unteransichten umgeht, wenn sie (der Container) Ziehenereignisse auf einem empfängt seiner Griffbereiche. Wenn Sie hier die Logik platzieren, können Sie jede Art von Unteransicht ziehen / skalieren und haben den zusätzlichen Vorteil, dass Sie nur eine Instanz der etwas schwereren Ansicht haben (im Gegensatz zu vielen Instanzen von Unteransichten, die eine kompliziertere Logik enthalten) / p>

Der grundlegende Mechanismus

Sobald Sie das entschieden haben, geht es nur darum, Ihre Unteransicht zu erstellen, die die Zeichnung verwaltet, NSTrackingArea-Instanzen verwaltet (für die Griffbereiche) und auf die entsprechenden Mausmethoden reagiert (nach unten, verschoben usw.). . Wenn jede Unteransicht ihre eigenen behandelt, werden sie ihre eigenen Verfolgungsbereiche, die Griffzeichnung und die bewegte Maus verwalten und ihren eigenen Rahmen als Antwort einstellen. Im Fall einer Containeransicht, die all dies für ihre Untersichten behandelt, verwaltet sie alle Verfolgungsbereiche aller Unteransichten und zeichnet ihre eigenen Griffe und stellt den Rahmen der Zieluntersicht ein (und die Unteransicht ist glücklicherweise unwissend über das Ganze). p>

Ich hoffe, dass dies Ihnen zumindest einen Überblick über mögliche Mechanismen gibt. Wäre ich nicht einfach aufgestanden und hätte meinen Morgenkaffee begonnen, wäre ich wahrscheinlich in der Lage, dies prägnanter zu schreiben, aber da hast du es. : -)

BEARBEITEN SIE 7 JAHRE SPÄTER

Da es nicht viel Details darüber gab, was das OP wollte, gab ich eine sehr allgemeine Antwort, aber ich sollte ein paar Punkte machen:

  • Ziehen Sie immer ein NSSplitView vor, wenn es möglich ist, dass es für Sie arbeitet (dh wenn die Ansichten miteinander ausgerichtet sind und den Platz der gemeinsamen Containeransicht teilen). In einer geteilten Ansicht können Sie Griffbereiche usw. anpassen und all dies kostenlos für Ihre Unteransicht verwenden.
  • AutoLayout war nicht vorhanden, als ich diese Antwort geschrieben habe, und es macht sehr kompliziert, eine eigene Lösung für das Szenario "View-handling-multiple-sizable-subviews" zu erstellen.
  • Wenn Sie wirklich ein UI-Element benötigen, das innerhalb eines Containers gezogen / verkleinert werden kann, versuchen Sie CALayers in einer Master-Ansicht zu verwenden, die die gesamte Layout- / Dimensionierungslogik beherrscht.
  • Wenn Sie das oben genannte nicht tun können (dh die Größe veränderbarer Ansichten enthält komplexe Steuerelemente und Layout, hat ihr eigenes NSViewController usw.), versuchen Sie einen hybriden Ansatz (verwenden Sie Ebenen, um zwischengespeicherte Bilder von nicht ausgewählten Ansichten anzuzeigen und fügen Sie nur eine vollständige, interaktive umfangreiche Teilansicht für den ausgewählten Artikel (oder Unteransichten für Artikel) hinzu.
  • Wegen der Komplexität von AutoLayout kann ich den wirklich ziehbaren Subview-Ansatz überhaupt nicht empfehlen, es sei denn, es ist unvermeidbar. Wenn Sie eine Ansicht entwerfen, die bewegliche, umfangreiche Objekte enthält, ist es am besten (und am effizientesten), alles in diese Ansicht zu übernehmen. Beispiel: Eine Grafik-App mit vielen Formen sollte eine Canvas-Ansicht haben, die die Formen (und alle GUI-Dekorationen wie Größe / Ziehgriffe usw.) mit CALayers darstellt. Dies nutzt die Grafikbeschleunigung und ist weit effizienter als ein Bündel (sehr ressourcenintensiver) NSView -Unterviews. Die gesamte Bewegungs- / Größen- / Auswahllogik wird von der "Canvas-Ansicht" gehandhabt und die einzigen Untersichten können überlagerte Steuerelemente sein. Wenn jedoch Canvas selbst in einer Bildlaufansicht eingeschlossen werden muss, empfiehlt es sich, NSScrollView machinery zu verwenden Overlay-Ansichten für diesen Zweck).
  • Wenn Sie eine Ansicht entwerfen, die viele Dinge zeichnet (für die Sie definitiv Ebenen verwenden sollten, um diese Dinge darzustellen), aber nur eins auswählen, ist die Vorgehensweise zum Hinzufügen einer Unteransicht sogar mit AutoLayout. Wenn das "zur Bearbeitung ausgewählt" -Ding über viele komplexe Steuerelemente verfügt, die beim Bearbeiten sichtbar werden, ist eine "Editor-Unteransicht" mit begleitendem Ansichtscontroller sinnvoll und ein guter Kompromiss in der Wartbarkeit (da der Ansichtscontroller alle Bearbeitungsfunktionen / UI-Funktionen abgrenzt) .Komplexität der Containeransicht (weil eine Unteransicht die Ressourcenbank nicht bricht und temporäre AutoLayout-Einschränkungen beibehält, um ihre Position während der Größenänderung der Containeransicht und des Editors nicht übermäßig komplex zu halten).
  • All das setzt macOS voraus; wenn man für iOS designt, beugt sich definitiv nach hinten, um Ebenen und die neue Drag-and-Drop-Maschinerie zu verwenden, von der ich derzeit sehr wenig weiß.

Zusammenfassend war die Antwort sowohl unvollständig als auch etwas veraltet, so dass ich meinen ursprünglichen Ratschlag nicht so gut finde, wie er es heute sein könnte.

    
Joshua Nozzi 10.10.2010, 14:13
quelle
0

Anstatt Ansichten zu verwenden, können Sie Fenster verwenden und die Stilmaske des Fensters auf NSResizableWindowMask setzen.

Eine andere Option ist die Verwendung einer NSSsplitView, wenn Sie zwei größenverstellbare, zusammenhängende Subviews haben.

    
Amber Haq Dixon 18.09.2013 21:06
quelle

Tags und Links