Anda tidak menggambarkan skala-untuk-pas; Anda menggambarkan aspek-fit. (Saya telah mengedit pertanyaan Anda dalam hal ini.) Subview menjadi sebesar mungkin dengan tetap mempertahankan rasio aspek dan sepenuhnya masuk ke dalam induknya.
Bagaimanapun, Anda dapat melakukan ini dengan tata letak otomatis. Anda dapat melakukannya sepenuhnya di IB pada Xcode 5.1. Mari kita mulai dengan beberapa tampilan:
Tampilan hijau muda memiliki rasio aspek 4: 1. Tampilan hijau gelap memiliki rasio aspek 1: 4. Saya akan mengatur batasan sehingga tampilan biru memenuhi bagian atas layar, tampilan merah muda memenuhi bagian bawah layar, dan setiap tampilan hijau melebar sebanyak mungkin dengan tetap mempertahankan rasio aspek dan menyesuaikannya dengan wadah.
Pertama, saya akan membuat batasan pada keempat sisi tampilan biru. Saya akan menempelkannya ke tetangga terdekat di setiap tepi, dengan jarak 0. Saya pastikan untuk mematikan margin:
Perhatikan bahwa saya belum memperbarui bingkai. Saya merasa lebih mudah untuk meninggalkan ruang di antara tampilan ketika membuat batasan, dan hanya mengatur konstanta ke 0 (atau apa pun) dengan tangan.
Selanjutnya, saya jepit tepi kiri, bawah, dan kanan tampilan pink ke tetangga terdekat. Saya tidak perlu mengatur batasan tepi atas karena tepi atasnya sudah dibatasi ke tepi bawah tampilan biru.
Saya juga membutuhkan batasan ketinggian yang sama antara tampilan pink dan biru. Ini akan membuat mereka masing-masing mengisi setengah layar:
Jika saya memberi tahu Xcode untuk memperbarui semua frame sekarang, saya mendapatkan ini:
Jadi kendala yang saya buat sejauh ini benar. Saya membatalkan itu dan mulai bekerja pada tampilan hijau muda.
Menyesuaikan aspek tampilan hijau muda membutuhkan lima kendala:
- Kendala rasio aspek prioritas yang diperlukan pada tampilan hijau muda. Anda dapat membuat batasan ini dalam xib atau storyboard dengan Xcode 5.1 atau yang lebih baru.
- Batasan prioritas yang diperlukan membatasi lebar tampilan hijau muda menjadi kurang dari atau sama dengan lebar wadahnya.
- Batasan prioritas tinggi yang mengatur lebar tampilan hijau muda menjadi sama dengan lebar wadahnya.
- Batasan prioritas yang diperlukan membatasi ketinggian tampilan hijau muda menjadi kurang dari atau sama dengan ketinggian wadahnya.
- Batasan prioritas tinggi yang mengatur ketinggian tampilan hijau muda menjadi sama dengan ketinggian wadahnya.
Mari kita pertimbangkan dua batasan lebar. Batasan yang kurang dari atau sama dengan sendirinya, tidak cukup untuk menentukan lebar tampilan hijau terang; banyak lebar akan sesuai dengan kendala. Karena ada ambiguitas, autolayout akan mencoba memilih solusi yang meminimalkan kesalahan pada kendala lain (prioritas tinggi tetapi tidak diperlukan). Meminimalkan kesalahan berarti membuat lebar sedekat mungkin dengan lebar wadah, sementara tidak melanggar batasan yang diperlukan kurang dari atau sama.
Hal yang sama terjadi dengan batasan ketinggian. Dan karena batasan aspek-rasio juga diperlukan, ia hanya dapat memaksimalkan ukuran subview sepanjang satu sumbu (kecuali wadah kebetulan memiliki rasio aspek yang sama dengan subview).
Jadi pertama-tama saya membuat batasan rasio aspek:
Lalu saya membuat batasan lebar dan tinggi yang sama dengan wadah:
Saya perlu mengedit batasan ini menjadi batasan yang kurang dari atau sama dengan:
Selanjutnya saya perlu membuat set lain dengan lebar dan tinggi sama kendala dengan wadah:
Dan saya perlu membuat batasan baru ini kurang dari prioritas yang disyaratkan:
Akhirnya, Anda meminta subview dipusatkan di wadahnya, jadi saya akan membuat batasan-batasan itu:
Sekarang, untuk menguji, saya akan memilih controller tampilan dan meminta Xcode untuk memperbarui semua frame. Inilah yang saya dapatkan:
Ups! Subview telah diperluas untuk sepenuhnya mengisi wadahnya. Jika saya pilih, saya dapat melihat bahwa sebenarnya itu dipertahankan rasio aspek, tapi itu melakukan aspect- mengisi bukan sebuah aspect- fit .
Masalahnya adalah bahwa pada kendala yang kurang dari atau sama, itu penting pandangan mana yang ada di setiap ujung kendala, dan Xcode telah mengatur kendala yang berlawanan dari harapan saya. Saya dapat memilih masing-masing dari dua kendala dan membalikkan item pertama dan kedua. Sebagai gantinya, saya hanya akan memilih subview dan mengubah batasan menjadi lebih dari-atau-sama:
Xcode memperbarui tata letak:
Sekarang saya melakukan semua hal yang sama dengan tampilan hijau gelap di bagian bawah. Saya perlu memastikan rasio aspeknya adalah 1: 4 (Xcode mengubah ukurannya dengan cara yang aneh karena tidak memiliki kendala). Saya tidak akan menunjukkan langkah lagi karena mereka sama. Inilah hasilnya:
Sekarang saya dapat menjalankannya di simulator iPhone 4S, yang memiliki ukuran layar berbeda dari IB yang digunakan, dan uji rotasi:
Dan saya dapat menguji di dalam iPhone 6 simulator:
Saya telah mengunggah storyboard terakhir saya ke intisari ini untuk kenyamanan Anda.
Rob, jawaban Anda luar biasa! Saya juga tahu bahwa pertanyaan ini secara khusus tentang mencapai ini dengan menggunakan tata letak otomatis. Namun, hanya sebagai referensi, saya ingin menunjukkan bagaimana hal ini dapat dilakukan dalam kode. Anda mengatur tampilan atas dan bawah (biru dan merah muda) seperti yang ditunjukkan Rob. Kemudian Anda membuat custom
AspectFitView
:AspectFitView.h :
AspectFitView.m :
Selanjutnya, Anda mengubah kelas tampilan biru dan merah muda di storyboard menjadi
AspectFitView
s. Akhirnya Anda mengatur dua outlet ke viewcontroller AndatopAspectFitView
danbottomAspectFitView
dan mengaturnyachildView
diviewDidLoad
:Jadi tidak sulit untuk melakukan ini dalam kode dan masih sangat mudah beradaptasi dan bekerja dengan tampilan yang bervariasi dan rasio aspek yang berbeda.
Perbarui Juli 2015 : Temukan aplikasi demo di sini: https://github.com/jfahrenkrug/SPWKAspectFitView
sumber
Saya membutuhkan solusi dari jawaban yang diterima, tetapi dieksekusi dari kode. Cara paling elegan yang saya temukan adalah menggunakan kerangka Masonry .
sumber
Ini untuk macOS.
Saya memiliki masalah untuk menggunakan cara Rob untuk mencapai aspek fit pada aplikasi OS X. Tapi saya membuatnya dengan cara lain - Alih-alih menggunakan lebar dan tinggi, saya menggunakan ruang depan, belakang, atas dan bawah.
Pada dasarnya, tambahkan dua spasi utama di mana satu adalah> = 0 @ 1000 prioritas yang diperlukan dan yang lain adalah = 0 @ 250 prioritas rendah. Lakukan pengaturan yang sama untuk trailing, ruang atas dan bawah.
Tentu saja, Anda perlu mengatur rasio aspek dan pusat X dan pusat Y.
Dan kemudian pekerjaan selesai!
sumber
Saya mendapati diri saya menginginkan perilaku aspek- isi sehingga UIImageView akan mempertahankan rasio aspeknya sendiri dan sepenuhnya mengisi tampilan wadah. Yang membingungkan, UIImageView saya melanggar KEDUA prioritas tinggi sama dengan lebar dan tinggi sama kendala (dijelaskan dalam jawaban Rob) dan rendering pada resolusi penuh.
Solusinya adalah dengan menetapkan Prioritas Ketahanan Kompresi Konten UIImageView lebih rendah daripada prioritas kendala dengan lebar sama dan tinggi sama:
sumber
Ini adalah port jawaban @ rob_mayoff yang sangat baik untuk pendekatan kode-sentris, menggunakan
NSLayoutAnchor
objek dan porting ke Xamarin. Bagi saya,NSLayoutAnchor
dan kelas terkait telah membuat AutoLayout lebih mudah diprogram:sumber
Mungkin ini adalah jawaban terpendek, dengan Masonry , yang juga mendukung aspek-isi dan peregangan.
sumber