Tata Letak Otomatis membuat hidup saya sulit. Secara teori, itu akan sangat berguna ketika saya berganti, tapi sepertinya saya terus berjuang sepanjang waktu.
Saya telah membuat proyek demo untuk mencoba mencari bantuan. Adakah yang tahu cara membuat ruang di antara tampilan bertambah atau berkurang secara merata setiap kali tampilan diubah ukurannya?
Berikut adalah tiga label (spasi manual secara vertikal):
Yang saya inginkan adalah mereka mengubah ukuran spasi mereka (bukan ukuran tampilan) secara merata ketika saya memutar. Secara default, tampilan atas dan bawah melengkung ke tengah:
Jawaban:
Jadi pendekatan saya memungkinkan Anda untuk melakukan ini dalam pembangun antarmuka. Apa yang Anda lakukan adalah membuat 'tampilan spacer' yang telah Anda atur agar sesuai dengan ketinggian. Kemudian tambahkan batasan atas dan bawah ke label (lihat tangkapan layar).
Lebih khusus lagi, saya memiliki batasan teratas pada 'Tampilan Spacer 1' untuk melakukan superview dengan batasan ketinggian prioritas lebih rendah dari 1000 dan dengan Ketinggian yang Sama dengan semua 'tampilan spacer' lainnya. 'Spacer View 4' memiliki batasan ruang bawah untuk superview. Setiap label memiliki batasan atas dan bawah masing-masing untuk 'tampilan spacer' terdekat.
Catatan: Pastikan Anda TIDAK memiliki batasan ruang atas / bawah ekstra pada label Anda untuk ditinjau; hanya yang ke 'tampilan ruang'. Ini akan memuaskan karena kendala atas dan bawah ada di 'Space View 1' dan 'Spacer View 4'.
Duh 1: Saya menggandakan pandangan saya dan hanya meletakkannya dalam mode lansekap sehingga Anda bisa melihatnya bekerja
Duh 2: 'Tampilan spacer' bisa transparan.
Duh 3: Pendekatan ini bisa diterapkan secara horizontal.
sumber
LIHAT, TANPA SPACER!
Berdasarkan saran di bagian komentar pada jawaban asli saya, terutama saran bermanfaat @ Rivera, saya telah menyederhanakan jawaban asli saya.
Saya menggunakan gif untuk menggambarkan betapa sederhananya ini. Saya harap Anda menemukan gif bermanfaat. Kalau-kalau Anda memiliki masalah dengan gif, saya sudah menyertakan jawaban lama di bawah ini dengan tangkapan layar biasa.
Instruksi:
1) Tambahkan tombol atau label Anda. Saya menggunakan 3 tombol.
2) Tambahkan batasan x pusat dari setiap tombol ke superview:
3) Tambahkan batasan dari setiap tombol ke batasan tata letak bawah:
4) Sesuaikan kendala yang ditambahkan pada # 3 di atas sebagai berikut:
a) pilih batasannya, b) hapus konstanta (atur ke 0), c) ubah pengali sebagai berikut: ambil jumlah tombol + 1, dan mulai dari atas, atur pengali sebagai tombolCountPlus1: 1 , lalu tombolCountPlus1 : 2 , dan akhirnya buttonCountPlus1: 3 . (Saya jelaskan dari mana saya mendapat formula ini dari jawaban lama di bawah, jika Anda tertarik).
5) Ini demo berjalan!
Catatan: Jika tombol Anda memiliki ketinggian yang lebih besar maka Anda perlu mengkompensasi hal ini dalam nilai konstan karena batasannya adalah dari bagian bawah tombol.
Jawaban Lama
Terlepas dari apa yang dikatakan oleh dokumen Apple dan buku hebat Erica Sadun ( Auto Layout Demystified ), adalah mungkin untuk menyamakan tampilan ruang tanpa spacer. Ini sangat mudah dilakukan di IB dan dalam kode untuk sejumlah elemen yang ingin Anda tempatkan secara merata. Yang Anda butuhkan hanyalah rumus matematika yang disebut "rumus bagian". Lebih mudah dilakukan daripada menjelaskan. Saya akan melakukan yang terbaik dengan mendemonstrasikannya dalam IB, tetapi itu mudah dilakukan dalam kode.
Dalam contoh yang dimaksud, Anda akan melakukannya
1) mulai dengan mengatur setiap label untuk memiliki batasan tengah. Ini sangat mudah dilakukan. Cukup kendalikan drag dari setiap label ke bawah.
2) Tahan shift, karena Anda mungkin juga menambahkan kendala lain yang akan kita gunakan, yaitu, "ruang bawah ke panduan tata letak bawah".
3) Pilih "panduan tata ruang bawah ke bawah", dan "tengah secara horizontal dalam wadah". Lakukan ini untuk ketiga label.
Pada dasarnya, jika kita mengambil label yang koordinatnya ingin kita tentukan dan membaginya dengan jumlah total label ditambah 1, maka kita memiliki nomor yang dapat kita tambahkan ke IB untuk mendapatkan lokasi yang dinamis. Saya menyederhanakan formula, tetapi Anda bisa menggunakannya untuk mengatur jarak horizontal atau vertikal dan horizontal secara bersamaan. Ini sangat kuat!
Inilah pengganda kami.
Label1 = 1/4 = .25,
Label2 = 2/4 = .5,
Label3 = 3/4 = .75
(Sunting: @Rivera berkomentar bahwa Anda dapat menggunakan rasio langsung di bidang pengali, dan xCode dengan melakukan matematika!)
4) Jadi, mari kita pilih Label1 dan pilih batasan bawah. Seperti ini:
5) Pilih "Item Kedua" di Inspektur Atribut.
6) Dari drop down pilih "Reverse item pertama dan kedua".
7) Nol keluar dari nilai konstanta dan wC hAny. (Anda dapat menambahkan offset di sini jika Anda membutuhkannya).
8) Ini adalah bagian penting: Di bidang pengali tambahkan pengali pertama kami 0,25.
9) Ketika Anda mengaturnya, atur "Item pertama" ke "Tengah" karena kami ingin menempatkannya di tengah label y. Begini caranya semua itu harus terlihat.
10) Ulangi proses ini untuk setiap label dan pasang pengganda yang relevan: 0,5 untuk Label2, dan 0,75 untuk Label3. Inilah produk akhir dalam semua orientasi dengan semua perangkat ringkas! Sangat sederhana. Saya telah melihat banyak solusi yang melibatkan rim kode, dan spacer. Ini adalah solusi terbaik yang pernah saya lihat dalam masalah ini.
Pembaruan: @kraftydevil menambahkan bahwa panduan tata letak bawah hanya muncul di storyboard, bukan di xibs. Gunakan 'Bottom Space to Container' di xibs. Tangkapan yang bagus!
sumber
Solusi Interface Builder yang sangat cepat:
Agar sejumlah tampilan ditempatkan secara merata dalam superview, cukup berikan masing-masing batasan "Align Center X to superview" untuk tata letak horizontal, atau "Align Center Y superview" untuk tata letak vertikal, dan atur Pengali menjadi
N:p
( CATATAN: beberapa lebih beruntung denganp:N
- lihat di bawah )dimana
N = total number of views
, danp = position of the view including spaces
Posisi pertama adalah 1, lalu spasi, membuat posisi berikutnya 3, jadi p menjadi seri [1,3,5,7,9, ...]. Berfungsi untuk sejumlah tampilan.
Jadi, jika Anda memiliki 3 tampilan ke luar, sepertinya ini:
EDIT Note: Pilihan
N:p
ataup:N
tergantung pada urutan relasi dari kendala alignment Anda. Jika "Item Pertama" adalah Superview.Center, Anda dapat menggunakanp:N
, sedangkan jika Superview.Center adalah "Item Kedua", Anda dapat menggunakanN:p
. Jika ragu, coba saja keduanya ... :-)sumber
Pada iOS 9, Apple telah membuat ini sangat mudah dengan (lama ditunggu)
UIStackView
. Cukup pilih tampilan yang ingin Anda isi di Interface Builder dan pilih Editor -> Embed In -> Stack view. Tetapkan batasan lebar / tinggi / margin yang sesuai untuk tampilan tumpukan, dan pastikan untuk mengatur properti Distribusi ke 'Penempatan yang sama':Tentu saja, jika Anda perlu mendukung iOS 8 atau lebih rendah, Anda harus memilih salah satu opsi lain.
sumber
Saya telah naik rollercoaster cinta autolayout dan membencinya. Kunci untuk mencintai tampaknya menerima hal-hal berikut:
Yang mengatakan, apa yang Anda coba tidak mudah dan akan sulit untuk dicapai dalam pembangun antarmuka. Sangat mudah dilakukan dalam kode. Kode ini, dalam
viewDidLoad
, menciptakan dan menempatkan tiga label bagaimana Anda memintanya:Seperti yang saya katakan, kode ini jauh disederhanakan dengan beberapa metode kategori
UIView
, tetapi untuk kejelasan saya sudah melakukannya jauh di sini.Kategori ini ada di sini untuk mereka yang tertarik, dan memiliki metode untuk secara merata mengatur jarak tampilan di sepanjang sumbu tertentu.
sumber
Sebagian besar solusi ini bergantung pada jumlah item ganjil sehingga Anda dapat mengambil item tengah dan menempatkannya di tengah. Bagaimana jika Anda memiliki jumlah barang merata yang masih ingin Anda bagikan secara merata? Inilah solusi yang lebih umum. Kategori ini secara merata akan mendistribusikan sejumlah item di sepanjang sumbu vertikal atau horizontal.
Contoh penggunaan untuk mendistribusikan 4 label secara vertikal dalam superview mereka:
NSLayoutConstraint + EvenDistribution.h
NSLayoutConstraint + EvenDistribution.m
sumber
Cara yang benar dan termudah adalah dengan menggunakan Stack Views.
sumber
Lihat pustaka sumber terbuka PureLayout . Ini menawarkan beberapa metode API untuk mendistribusikan tampilan, termasuk varian di mana jarak antara setiap tampilan ditetapkan (ukuran tampilan bervariasi sesuai kebutuhan), dan di mana ukuran setiap tampilan ditetapkan (jarak antar tampilan bervariasi sesuai kebutuhan). Perhatikan bahwa semua ini dilakukan tanpa menggunakan "tampilan spacer".
Dari NSArray + PureLayout.h :
Karena itu semua open source, jika Anda tertarik untuk melihat bagaimana ini dicapai tanpa spacer tampilan lihat saja implementasinya. (Itu tergantung pada pengungkit baik untuk
constant
maupunmultiplier
untuk kendala.)sumber
Saya mengalami masalah yang sama dan menemukan posting ini. Namun, tidak ada jawaban yang tersedia saat ini memecahkan masalah dengan cara yang Anda inginkan. Mereka tidak membuat spasi sama, melainkan mendistribusikan pusat label secara merata. Penting untuk dipahami bahwa ini tidak sama. Saya telah membuat diagram kecil untuk menggambarkan hal ini.
Ada 3 tampilan, semuanya 20pt tinggi. Menggunakan salah satu metode yang disarankan mendistribusikan pusat pandangan secara merata dan memberi Anda tata letak bergambar. Perhatikan bahwa pusat-y dari tampilan diberi jarak yang sama. Namun, jarak antara tampilan superview dan tampilan atas adalah 15pt, sedangkan jarak antara tampilan tampilan hanya 5pt. Agar tampilan spasi sama, keduanya harus 10pt, yaitu semua panah biru harus 10pt.
Meskipun demikian, saya belum menemukan solusi generik yang bagus. Saat ini ide terbaik saya adalah memasukkan "spacing views" antara subview dan mengatur ketinggian tampilan spacing agar sama.
sumber
Saya bisa menyelesaikan ini sepenuhnya di IB:
Jadi jika Anda memiliki tiga label, atur pengganda ke masing-masing kendala tersebut ke 0,1666667, 0,5, 0,833333.
sumber
Saya menemukan metode yang sempurna dan sederhana. Tata letak otomatis tidak memungkinkan Anda untuk mengubah ukuran spasi secara merata, tetapi memungkinkan Anda untuk mengubah ukuran tampilan secara merata. Cukup taruh beberapa tampilan tak terlihat di antara bidang Anda dan beri tahu tata letak otomatis agar ukurannya tetap sama. Itu bekerja dengan sempurna!
Satu hal yang perlu diperhatikan; ketika saya mengurangi ukuran di perancang antarmuka, kadang-kadang menjadi bingung dan meninggalkan label di tempat itu, dan itu memiliki konflik jika ukuran diubah oleh jumlah yang ganjil. Kalau tidak, itu bekerja dengan sempurna.
sunting: Saya menemukan bahwa konflik menjadi masalah. Karena itu, saya mengambil salah satu batasan spasi, menghapusnya dan menggantinya dengan dua kendala, yang lebih besar dari atau sama dan kurang sama atau sama. Keduanya berukuran sama dan memiliki prioritas yang jauh lebih rendah daripada kendala lainnya. Hasilnya tidak ada konflik lebih lanjut.
sumber
Membangun jawaban Ben Dolman, ini mendistribusikan pandangan lebih merata (dengan padding, dll):
sumber
periksa https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html memiliki deskripsi yang bagus tentang menyelesaikan masalah Anda.
sumber
Dengan label, setidaknya ini berfungsi dengan baik:
@"H:|-15-[first(==second)]-[second(==third)]-[third(==first)]-15-|
Jika yang pertama memiliki lebar yang sama dengan yang kedua, dan yang kedua yang ketiga, dan yang ketiga yang pertama, maka mereka semua akan mendapatkan lebar yang sama ... Anda bisa melakukannya secara horizontal (H) dan vertikal (V).
sumber
versi 3 cepat
sumber
Saya tahu sudah lama sejak jawaban pertama, tapi saya baru saja menemukan masalah yang sama dan saya ingin berbagi solusi. Untuk generasi yang akan datang ...
Saya menetapkan pandangan saya pada viewDidLoad:
Dan kemudian, pada updateViewConstrains, pertama-tama saya menghapus semua batasan, kemudian saya membuat kamus tampilan dan kemudian saya menghitung ruang yang akan digunakan di antara tampilan. Setelah itu, saya hanya menggunakan Format Bahasa Visual untuk mengatur batasan:
Hal yang baik tentang metode ini adalah Anda harus melakukan sedikit matematika. Saya tidak mengatakan ini adalah solusi yang sempurna, tetapi saya bekerja untuk tata letak yang saya coba capai.
Saya harap ini membantu.
sumber
Berikut adalah solusi yang akan memusatkan secara vertikal sejumlah subview, meskipun ukurannya unik. Yang ingin Anda lakukan adalah membuat wadah tingkat menengah, tempatkan di superview, lalu taruh semua subview dalam wadah dan atur sesuai dengan satu sama lain. Namun yang terpenting, Anda juga harus membatasi mereka di bagian atas dan bawah wadah, sehingga wadah tersebut dapat berukuran dan dipusatkan di superview dengan benar. Dengan mencari ketinggian yang tepat dari subview-nya, wadah dapat secara vertikal terpusat.
Dalam contoh ini,
self
adalah superview di mana Anda memusatkan semua subview.sumber
Saya baru saja menyelesaikan masalah saya menggunakan fitur pengali. Saya tidak yakin itu bekerja untuk semua kasus, tetapi bagi saya itu bekerja dengan sempurna. Saya menggunakan Xcode 6.3 FYI.
Apa yang akhirnya saya lakukan adalah:
1) Pertama-tama menempatkan tombol saya pada layar lebar 320px seperti yang saya inginkan pada perangkat 320px.
2) Lalu saya menambahkan kendala Space terkemuka untuk melakukan superview pada semua tombol saya.
3) Kemudian saya memodifikasi properti dari ruang terdepan sehingga konstanta adalah 0 dan pengali adalah offset x dibagi dengan lebar layar (mis. Tombol pertama saya adalah 8px dari tepi kiri jadi saya mengatur pengali ke 8/320)
4) Maka langkah penting di sini adalah mengubah Item kedua dalam relasi kendala menjadi superview. Mengolah alih-alih superview.leading. Ini adalah kunci karena superview. Memimpin adalah 0 dan mengikuti dalam kasus saya adalah 320, jadi 8/320 adalah 8 px pada perangkat 320px, maka ketika lebar superview berubah menjadi 640 atau apa pun, tampilan semua bergerak pada rasio relatif terhadap lebar dari ukuran layar 320px. Matematika di sini jauh lebih sederhana untuk dipahami.
sumber
Banyak jawaban yang tidak benar, tetapi dapatkan banyak penghitungan. Di sini saya hanya menulis solusi secara pemrograman, tiga tampilan adalah perataan horizontal, tanpa menggunakan tampilan spacer , tetapi hanya berfungsi ketika lebar label diketahui saat digunakan dalam storyboard .
sumber
Ini jawaban lain. Saya menjawab pertanyaan serupa dan melihat tautan yang dirujuk ke pertanyaan ini. Saya tidak melihat jawaban yang mirip dengan jawaban saya. Jadi, saya berpikir untuk menulisnya di sini.
Dan lagi, ini dapat dilakukan dengan cukup mudah dengan iOS9 UIStackViews juga.
Perhatikan bahwa pendekatannya sama persis seperti di atas. Ini menambahkan empat tampilan wadah yang diisi sama dan tampilan ditambahkan ke setiap tampilan tumpukan yang disejajarkan di tengah. Tapi, versi UIStackView ini mengurangi beberapa kode dan terlihat bagus.
sumber
Pendekatan lain mungkin memiliki label atas dan bawah memiliki kendala relatif terhadap tampilan atas dan bawah, masing-masing, dan memiliki tampilan tengah memiliki kendala atas dan bawah relatif masing-masing dengan tampilan pertama dan ketiga.
Perhatikan bahwa Anda memiliki kontrol lebih besar atas kendala daripada yang mungkin terlihat dengan menyeret tampilan dekat satu sama lain hingga muncul garis putus-putus memandu - ini menunjukkan kendala antara dua objek yang akan dibentuk alih-alih antara objek dan superview.
Dalam hal ini Anda kemudian ingin mengubah batasan menjadi "Lebih besar dari atau sama dengan" nilai yang diinginkan, alih-alih "sama dengan" untuk memungkinkan mereka mengubah ukuran. Tidak yakin apakah ini akan melakukan apa yang Anda inginkan.
sumber
Cara yang sangat mudah untuk menyelesaikan ini di InterfaceBuilder:
Atur label tengah (label2) ke "Pusat Horisontal dalam Wadah" dan "Pusat Vertikal dalam Wadah"
Pilih label tengah dan label atas (label1 + label2) dan tambahkan DUA kendala untuk Penempatan Vertikal. Satu dengan Greater Than atau Equal jarak min. Satu dengan Less Than atau Equal the max spacing.
Hal yang sama untuk label tengah dan label bawah (label2 + label3).
Selain itu Anda juga dapat menambahkan dua batasan pada label1 - Top Space To SuperView dan dua kendala untuk label2 - Bottom Space To SuperView.
Hasilnya adalah bahwa semua 4 spacing akan mengubah ukurannya secara merata.
sumber
Saya telah membuat fungsi yang mungkin membantu. Contoh penggunaan ini:
akan menyebabkan distribusi vertikal (maaf tidak memiliki 10 reputasi untuk menanamkan gambar). Dan jika Anda mengubah sumbu dan beberapa nilai margin:
Anda akan mendapatkan distribusi horizontal itu .
Saya pemula di iOS tetapi voaà!
EvenDistribution.h
EvenDistribution.m
sumber
Ya, Anda bisa melakukan ini hanya dalam pembangun antarmuka dan tanpa menulis kode - satu peringatan adalah bahwa Anda mengubah ukuran label daripada mendistribusikan spasi. Dalam hal ini, sejajarkan Label 2's X dan Y ke superview sehingga diperbaiki di tengah. Kemudian atur ruang vertikal label 1 ke superview dan label 2 ke standar, ulangi untuk label 3. Setelah mengatur label 2, cara termudah untuk mengatur label 1 dan 3 adalah mengubah ukurannya sampai label tersebut patah.
Berikut adalah tampilan horizontal, perhatikan bahwa ruang vertikal antara label 1 dan 2 diatur ke standar:
Dan inilah versi potretnya:
Saya menyadari mereka tidak benar-benar berjarak 100% sama antara garis dasar karena perbedaan antara ruang standar antara label dan ruang standar untuk superview. Jika itu mengganggu Anda, atur ukuran ke 0 dan bukan standar
sumber
Saya menetapkan nilai lebar hanya untuk item pertama (> = lebar) dan jarak minimum antara setiap item (> = jarak). Lalu saya menggunakan Ctrl untuk menyeret item kedua, ketiga ... pada yang pertama untuk menghubungkan dependensi antar item.
sumber
Terlambat ke pesta tapi aku punya solusi untuk membuat menu secara horizontal dengan spasi. Ini dapat dengan mudah dilakukan menggunakan
==
NSLayoutConstraintsumber
Android memiliki metode chaining views bersama dalam sistem tata letak berbasis kendala yang ingin saya tiru. Pencarian membawa saya ke sini tetapi tidak ada jawaban yang cukup berhasil. Saya tidak ingin menggunakan StackViews karena mereka cenderung membuat saya lebih sedih daripada menghemat waktu. Saya akhirnya menciptakan solusi yang menggunakan UILayoutGuides ditempatkan di antara tampilan. Mengontrol lebarnya memungkinkan berbagai jenis distribusi, gaya berantai dalam bahasa Android. Fungsi menerima anchor yang memimpin dan mengikuti bukannya tampilan induk. Ini memungkinkan rantai ditempatkan di antara dua tampilan sewenang-wenang daripada didistribusikan di dalam tampilan induk. Itu memang menggunakan
UILayoutGuide
yang hanya tersedia di iOS 9+ tapi itu seharusnya tidak menjadi masalah lagi.sumber
Saya ingin menyelaraskan 5 gambar secara horizontal, jadi saya akhirnya mengikuti respons Mete dengan sedikit perbedaan.
Gambar pertama akan dipusatkan secara horizontal dalam wadah yang sama dengan 0 dan pengganda 1: 5:
Gambar kedua akan dipusatkan secara horizontal dalam wadah yang sama dengan 0 dan pengganda 3: 5:
Dan seperti itu untuk sisa gambar. Misalnya, gambar kelima (dan yang terakhir) akan dipusatkan secara horizontal dalam wadah yang sama dengan 0 dan pengganda 9: 5:
Seperti yang dijelaskan Mete, urutannya adalah 1, 3, 5, 7, 9, dll. Posisi mengikuti logika yang sama: posisi pertama adalah 1, lalu spasi, kemudian posisi berikutnya 3, dan seterusnya.
sumber
Mengapa Anda tidak membuat tableView dan membuatnya
isScrollEnabled = false
sumber