autolayout - membuat ketinggian tampilan menjadi relatif terhadap setengah tinggi tampilan super

137

telah masuk ke pembayaran otomatis baru-baru ini dan saya terjebak pada apa yang tampaknya seperti contoh masalah yang sangat sepele. Saya memiliki pandangan yang ingin saya duduki di bagian atas layar, dan mengambil setengah dari tinggi layar. Sederhana sebelum tata letak otomatis - cukup tempelkan di tempatnya dan beri tahu untuk meluaskan secara vertikal saat tampilan super berubah ukuran.

Sekarang, saya tidak bisa seumur hidup saya melihat bagaimana melakukannya. Inilah yang saya dapatkan saat mencoba menyiapkan ini:

autolayout blues

Batasan ruang bawah disetel ke "sama dengan 284", yang mutlak dan sama sekali tidak berguna bagi saya ketika saya mengubah ke tata letak iPhone4, karena itu membuat ruang 284 poin di bagian bawah layar, dan memperkecil tampilan menjadi tidak lagi setengah ukuran layar. Dan tidak ada cara untuk menyetel batasan tersebut agar sama dengan beberapa pecahan dari ketinggian tampilan lainnya ..

Setelah berjuang beberapa saat, satu-satunya cara yang dapat saya pikirkan untuk melakukan ini adalah dengan memperkenalkan tampilan lain di bawah tampilan ini, menyematkan ketinggian mereka secara merata, meminta mereka duduk di atas dan di bawah satu sama lain, dan kemudian mengatur tampilan kedua (bawah) agar tidak terlihat. .. yang sepertinya agak jelek!

Apakah saya melewatkan sesuatu yang jelas? ..

Memberikan
sumber
1
Saya tidak berpikir itu jelek, tapi trik cerdas untuk mendapatkan apa yang Anda inginkan dengan IB. Saya telah melakukan ini, dan ketika Anda menggunakan nama elemen yang tepat, Anda dapat menjelaskan apa yang sedang terjadi. Anda bahkan dapat memiliki elemen ketiga pada posisi yang berbeda, atau pusat, mengubah ukuran berdasarkan dua subview ini.
Jelle

Jawaban:

169

Ini sekarang dimungkinkan di IB sejak [setidaknya] Xcode 5.1.1. Meskipun saya butuh waktu untuk mengetahui bahwa ini sebenarnya sangat sederhana:

Pertama buat batasan perataan atas dasar (Anda juga perlu mengatur batasan bawah, kiri, dan kanan, seperti biasa). Kemudian pilih batasan dan arahkan ke inspektur atribut :

Demonstrasi langkah-langkah di atas

Kemudian Anda dapat mengatur pengali. Jika Anda menginginkannya 50% dari tampilan super biarkan di 1, karena sejajar per pusat super. Ini juga cara yang bagus untuk membuat tampilan yang merupakan persentase lain juga (seperti 25% dari tampilan super)

Demonstrasi langkah kedua di atas

Firo
sumber
bagus :) Saya pikir posting ini harus ditandai sebagai jawaban yang diterima :) Pengembang iOS sering lebih memilih Solusi Pembuat Antarmuka daripada solusi seperti kode
hqt
@hqt, Terima kasih. Saya pikir ketika jawaban yang diterima ditulis metode ini tidak tersedia. Terkadang penanya tidak meninjau kembali pertanyaan lama atau peduli untuk mengubah jawaban yang diterima. Tetapi pada akhirnya saya di sini hanya untuk membantu, senang itu terjadi!
Firo
3
Saya sedikit bingung. Saya mencoba ini tetapi hanya memusatkan pandangan ke superview, tidak menyesuaikan ketinggian tampilan.
Dean
@Dean, Anda perlu memastikan bahwa First Itemini View.Toptidak View.Center Y. Jika tidak, ya itu hanya akan memusatkannya. Anda juga perlu memastikan pembatas lain disetel dengan benar untuk menangani tepi tampilan lainnya.
Firo
1
View.Top Sama dengan Superview. Pengali pusat Y 1 tidak memberi Anda ketinggian. Jawaban ini tidak lengkap. Yang harus Anda lakukan adalah memikirkan apa yang Anda katakan dan Anda bisa melihatnya memberi Anda garis di tengah! Saya akan mengedit jawaban ini untuk memperjelas kendala lain apa yang Anda bicarakan.
smileBot
185

Solusi papan cerita di mana Anda dapat mengatur rasio yang tepat antara tampilan apa pun:

Setel batasan kesetaraan tinggi

Sekarang:

Edit pengali batasan

KEUNTUNGAN!!!

Hasil

PS Perhatikan juga bahwa metode ini bekerja dengan tampilan pada tingkat bersarang yang berbeda dan (jelas) berlaku untuk lebar

PPS terkadang mungkin berguna untuk "membalikkan item pertama dan kedua" dari batasan atau menyetel pengganda terbalik (misalnya 2, bukan 0,5) (tetapi metode ini tidak membantu jika Anda tidak memahami bagaimana tampilan terkait satu sama lain).

Fyodor Volchyok
sumber
1
Langkah 2 sepertinya tidak berhasil untuk saya. Saya tidak dapat memilih apa pun di panel kecuali mengaktifkan 'Batasan ke margin'. Saya mencoba menyetel lebar UIImageView di UITableViewCell menjadi 50% dari tampilan konten.
DrMickeyLauer
2
PEMBARUAN: Jelas pembuat antarmuka tidak mengizinkan tampilan konten menjadi target eksplisit dari batasan tata letak otomatis apa pun. Saya harus memasukkan subview dummy sebagai anak dari tampilan konten untuk membuat ini berfungsi.
DrMickeyLauer
1
Ini bekerja untuk saya. Anda perlu memilih dua tampilan dalam daftar, bukan layar pembuat. untuk persentase membagi tampilan yang lebih kecil dengan tampilan yang lebih besar untuk mendapatkan nilai pengali contoh tampilan lebih kecil 25, tampilan lebih besar 135 - 25/135 = 0,185. Setel ini sebagai nilai pengali untuk mendapatkan tampilan bahwa pada x1 dan x2 = 25 tetapi meningkatkan skala dengan lebih besar 6 dan 6 plus dll
latenitecoder
1
Ini berhasil untuk saya, tetapi harap perhatikan bahwa saya juga harus menambahkan tiga batasan yang menyetel batasan margin subview ke 0. Terima kasih
raddevus
Ini harus menjadi jawaban yang diterima. Pertama saya mencoba jawaban yang diterima. Itu tidak berhasil, lalu saya gulir ke bawah dan saya melihat jawaban ini dan berhasil. Terima kasih!
Mihir Oza
31

Setelah beberapa waktu, saya menemukan yang berikut ini.

Saya mencatatnya sebagai jawaban tetapi itu tidak terlalu memuaskan, karena mengasumsikan Anda tidak dapat benar-benar melakukan ini di Interface Builder, tetapi batasan yang benar dapat ditambahkan dalam kode setelahnya sebagai:

- (void) viewWillAppear:(BOOL)animated
{

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:upperview
                                                                 attribute:NSLayoutAttributeHeight 
                                                                 relatedBy:0 
                                                                    toItem:self.view
                                                                 attribute:NSLayoutAttributeHeight
                                                                multiplier:.5 
                                                                  constant:0];
    [self.view addConstraint:constraint];

}

Pada dasarnya, ini menetapkan pengali 0,5 terhadap ketinggian tampilan sendiri, yang bekerja pada tampilan atas. Saya harus menetapkan prioritas batasan ruang vertikal bawah di IB menjadi lebih rendah dari 1000 untuk menghindari sekumpulan pesan runtime tentang melanggar batasan juga.

Jadi, jika ada yang bisa menunjukkan bagaimana melakukan ini di Interface Builder, itu akan menjawab pertanyaan saya dengan lebih baik, jika tidak, saya rasa ini sebagus yang didapat (untuk saat ini) ???

Memberikan
sumber
3
Saya pikir ini sebagus yang didapat sekarang. Alangkah baiknya jika Apple memberi kita akses ke nilai pengali di IB, sehingga bisa diset dan juga konstanta.
rdelmar
3
Bagi siapa pun yang melihat jawaban ini, Xcode 5.1 sekarang memungkinkan Anda untuk mengatur pengali melalui Interface Builder. Sekarang saya dapat mengonfigurasi tampilan yang tingginya setengah dari superview mereka semua melalui IB.
Mark Krenek
9

Sedikit lebih mudah dan lebih lurus ke depan daripada metode daripada jawaban Fyodor Volchyok. -Tahan tombol kontrol dan klik subview. -Masih menahan tombol perintah, seret kursor ke superview lalu klik superview. -Pilih "Rasio Aspek".

masukkan deskripsi gambar di sini

-Lalu klik Size Inspector. -Kemudian klik dua kali pada batasan. masukkan deskripsi gambar di sini

-Pastikan "tinggi" dipilih untuk kedua item. masukkan deskripsi gambar di sini

-Lalu ubah "Pengganda" menjadi 0,5 untuk setengah layar, atau bagian mana pun dari tampilan super yang Anda inginkan. masukkan deskripsi gambar di sini

pengguna444333222
sumber
Pendekatan yang mudah dan cepat! Terima kasih kawan
Abdullah Saeed
7

Ada juga kemungkinan lain dalam kode jika Anda memiliki 2 tampilan yang keduanya harus memiliki ketinggian yang sama: cukup atur tinggi view2 ke ketinggian view1 (trik di sini adalah tidak mengatur tinggi view1 secara eksplisit).

    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
                            options:0
                            metrics:nil
                              views:viewsDict]];
brainray
sumber
Tidak sadar Anda bisa mereferensikan tampilan lain untuk lebar / tinggi seperti itu. Ini adalah jawaban IMO terbersih jika Anda sudah dalam bahasa format visual.
loeschg
Contoh @brainray juga dijelaskan di developer.apple.com
alecs.popa
0

Versi cepat dari jawaban Mete:

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.



    upperView.translatesAutoresizingMaskIntoConstraints = false


    var constraint = NSLayoutConstraint(item: upperView,
                                        attribute: NSLayoutAttribute.top,
                                        relatedBy: NSLayoutRelation.equal,
                                        toItem: self.view,
                                        attribute: NSLayoutAttribute.top,
                                        multiplier: 1,
                                        constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.height,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.height,
                                    multiplier: 0.5,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.leading,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.leading,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.trailing,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.trailing,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


}
pengguna444333222
sumber