Sie beschreiben nicht Scale-to-Fit. Sie beschreiben Aspekt-Fit. (Ich habe Ihre Frage in dieser Hinsicht bearbeitet.) Die Unteransicht wird so groß wie möglich, während das Seitenverhältnis beibehalten wird und vollständig in das übergeordnete Element passt.
Auf jeden Fall können Sie dies mit automatischem Layout tun. Sie können dies vollständig in IB ab Xcode 5.1 tun. Beginnen wir mit einigen Ansichten:
Die hellgrüne Ansicht hat ein Seitenverhältnis von 4: 1. Die dunkelgrüne Ansicht hat ein Seitenverhältnis von 1: 4. Ich werde Einschränkungen so einrichten, dass die blaue Ansicht die obere Hälfte des Bildschirms ausfüllt, die rosa Ansicht die untere Hälfte des Bildschirms ausfüllt und jede grüne Ansicht so weit wie möglich erweitert wird, während das Seitenverhältnis beibehalten und in das Bild passt Container.
Zuerst werde ich Einschränkungen auf allen vier Seiten der blauen Ansicht erstellen. Ich werde es an jedem Rand mit einem Abstand von 0 an den nächsten Nachbarn heften. Ich stelle sicher, dass die Ränder ausgeschaltet sind:
Beachten Sie, dass ich den Frame noch nicht aktualisiere. Ich finde es einfacher, beim Einrichten von Einschränkungen Platz zwischen den Ansichten zu lassen und die Konstanten einfach von Hand auf 0 (oder was auch immer) zu setzen.
Als nächstes stecke ich den linken, unteren und rechten Rand der rosa Ansicht an den nächsten Nachbarn. Ich muss keine Oberkantenbeschränkung einrichten, da die Oberkante bereits auf die Unterkante der blauen Ansicht beschränkt ist.
Ich brauche auch eine Einschränkung gleicher Höhe zwischen der rosa und der blauen Ansicht. Dadurch füllen sie jeweils die Hälfte des Bildschirms aus:
Wenn ich Xcode anweise, alle Frames jetzt zu aktualisieren, erhalte ich Folgendes:
Die Einschränkungen, die ich bisher festgelegt habe, sind also korrekt. Ich mache das rückgängig und beginne mit der Arbeit an der hellgrünen Ansicht.
Die Aspektanpassung der hellgrünen Ansicht erfordert fünf Einschränkungen:
- Eine Einschränkung des Seitenverhältnisses mit erforderlicher Priorität für die hellgrüne Ansicht. Sie können diese Einschränkung in einer XIB oder einem Storyboard mit Xcode 5.1 oder höher erstellen.
- Eine Einschränkung mit erforderlicher Priorität, die die Breite der hellgrünen Ansicht auf weniger als oder gleich der Breite ihres Containers begrenzt.
- Eine Einschränkung mit hoher Priorität, mit der die Breite der hellgrünen Ansicht gleich der Breite des Containers festgelegt wird.
- Eine Einschränkung mit erforderlicher Priorität, die die Höhe der hellgrünen Ansicht auf weniger als oder gleich der Höhe ihres Containers begrenzt.
- Eine Einschränkung mit hoher Priorität, mit der die Höhe der hellgrünen Ansicht gleich der Höhe des Containers festgelegt wird.
Betrachten wir die beiden Breitenbeschränkungen. Die weniger als oder gleiche Einschränkung allein reicht nicht aus, um die Breite der hellgrünen Ansicht zu bestimmen. Viele Breiten passen zur Einschränkung. Da es Unklarheiten gibt, versucht Autolayout, eine Lösung zu wählen, die den Fehler in der anderen Einschränkung (mit hoher Priorität, aber nicht erforderlich) minimiert. Um den Fehler zu minimieren, muss die Breite so nahe wie möglich an der Breite des Containers liegen, ohne die erforderliche Einschränkung zu verletzen, die kleiner oder gleich ist.
Das gleiche passiert mit der Höhenbeschränkung. Und da die Seitenverhältnisbeschränkung ebenfalls erforderlich ist, kann sie nur die Größe der Unteransicht entlang einer Achse maximieren (es sei denn, der Container hat zufällig das gleiche Seitenverhältnis wie die Unteransicht).
Also erstelle ich zuerst die Seitenverhältnisbeschränkung:
Dann erstelle ich mit dem Container gleiche Breiten- und Höhenbeschränkungen:
Ich muss diese Einschränkungen so bearbeiten, dass sie weniger als oder gleich sind:
Als nächstes muss ich einen weiteren Satz von Einschränkungen für Breite und Höhe mit dem Container erstellen:
Und ich muss diese neuen Einschränkungen weniger als erforderlich machen:
Schließlich haben Sie darum gebeten, dass die Unteransicht in ihrem Container zentriert wird, damit ich die folgenden Einschränkungen einrichte:
Zum Testen wähle ich jetzt den View Controller aus und fordere Xcode auf, alle Frames zu aktualisieren. Das bekomme ich:
Hoppla! Die Unteransicht wurde erweitert, um den Container vollständig zu füllen. Wenn ich es wählen, kann ich sehen , dass in der Tat ist es das Seitenverhältnis beibehalten wird , aber es ist ein aspekt tun Füllung anstelle eines aspekt fit .
Das Problem ist, dass es bei einer Einschränkung, die kleiner oder gleich ist, darauf ankommt, welche Ansicht sich an jedem Ende der Einschränkung befindet, und Xcode die Einschränkung entgegen meiner Erwartung eingerichtet hat. Ich könnte jede der beiden Einschränkungen auswählen und die ersten und zweiten Elemente umkehren. Stattdessen wähle ich einfach die Unteransicht aus und ändere die Einschränkungen so, dass sie größer oder gleich sind:
Xcode aktualisiert das Layout:
Jetzt mache ich die gleichen Dinge mit der dunkelgrünen Ansicht unten. Ich muss sicherstellen, dass das Seitenverhältnis 1: 4 ist (Xcode hat die Größe auf seltsame Weise geändert, da es keine Einschränkungen gab). Ich werde die Schritte nicht mehr zeigen, da sie gleich sind. Hier ist das Ergebnis:
Jetzt kann ich es im iPhone 4S-Simulator ausführen, der eine andere Bildschirmgröße als der verwendete IB hat, und die Rotation testen:
Und ich kann im iPhone 6 Simulator testen:
Ich habe mein endgültiges Storyboard zu Ihrer Übersicht hochgeladen .
Rob, deine Antwort ist großartig! Ich weiß auch, dass es bei dieser Frage speziell darum geht, dies durch die Verwendung des automatischen Layouts zu erreichen. Als Referenz möchte ich jedoch zeigen, wie dies im Code möglich ist. Sie richten die Draufsicht und die Unteransicht (blau und pink) genau so ein, wie Rob es gezeigt hat. Dann erstellen Sie eine benutzerdefinierte
AspectFitView
:AspectFitView.h :
AspectFitView.m :
Als Nächstes ändern Sie die Klasse der blauen und rosa Ansichten im Storyboard in
AspectFitView
s. Schließlich setzen Sie zwei Auslässe auf Ihre ViewcontrollertopAspectFitView
undbottomAspectFitView
und setzen ihrechildView
s inviewDidLoad
:Es ist also nicht schwer, dies im Code zu tun, und es ist immer noch sehr anpassungsfähig und funktioniert mit Ansichten unterschiedlicher Größe und unterschiedlichen Seitenverhältnissen.
Update Juli 2015 : Eine Demo-App finden Sie hier: https://github.com/jfahrenkrug/SPWKAspectFitView
quelle
Ich brauchte eine Lösung aus der akzeptierten Antwort, die aber aus dem Code ausgeführt wurde. Der eleganteste Weg, den ich gefunden habe, ist die Verwendung von Masonry Framework .
quelle
Dies ist für macOS.
Ich habe Probleme, Robs Methode zu verwenden, um eine Aspektanpassung an die OS X-Anwendung zu erreichen. Aber ich habe es auf eine andere Weise geschafft - Anstatt Breite und Höhe zu verwenden, habe ich führenden, nachfolgenden, oberen und unteren Raum verwendet.
Fügen Sie grundsätzlich zwei führende Leerzeichen hinzu, wobei eines die erforderliche Priorität> = 0 @ 1000 und das andere die niedrige Priorität = 0 @ 250 hat. Nehmen Sie die gleichen Einstellungen für den hinteren, oberen und unteren Bereich vor.
Natürlich müssen Sie das Seitenverhältnis und das Zentrum X und das Zentrum Y einstellen.
Und dann ist die Arbeit erledigt!
quelle
Ich wollte ein Aspektfüllungsverhalten , damit eine UIImageView ihr eigenes Seitenverhältnis beibehält und die Containeransicht vollständig ausfüllt. Verwirrenderweise hat mein UIImageView BEIDE Einschränkungen mit hoher Priorität für gleiche Breite und gleiche Höhe (beschrieben in Robs Antwort) gebrochen und mit voller Auflösung gerendert.
Die Lösung bestand einfach darin, die Priorität des Inhaltskomprimierungswiderstands von UIImageView niedriger als die Priorität der Einschränkungen für gleiche Breite und gleiche Höhe festzulegen:
quelle
Dies ist eine Portierung von @ rob_mayoffs hervorragender Antwort auf einen codezentrierten Ansatz, bei dem
NSLayoutAnchor
Objekte verwendet und auf Xamarin portiert werden. Für michNSLayoutAnchor
und verwandte Klassen hat das Programmieren von AutoLayout viel einfacher gemacht:quelle
Vielleicht ist dies die kürzeste Antwort mit Masonry , das auch das Füllen und Strecken von Aspekten unterstützt.
quelle