Bagaimana saya bisa menggunakan Autolayout untuk menetapkan batasan pada UIScrollview saya?

176

Saya telah menghabiskan dua hari mencoba berbagai solusi untuk pendekatan Mixed and Pure Autolayout untuk mencapai apa yang merupakan pengaturan scrollview sepele sebelum autolayout, dan sekarang sudah resmi - saya pasti terlalu bodoh. Saya mengatur ini sebagian besar di Storyboard (well, begitulah adanya).

Jadi inilah permintaan saya untuk bantuan.

Viewtree:

UIView
-UIView
-UIView
..-UIScrollview
...-UIButton
...-UIButton
...-UIButton

Tombol-tombol tersebut seharusnya bergulir secara horizontal (kiri ke kanan dan sebaliknya). Dapatkah seseorang tolong beri tahu saya cara mengatur batasan untuk mencapai ini menggunakan Autolayout murni ???

-

Saya telah mencoba pendekatan campuran, seperti:

UIView
- UIView
- UIView
..-UIScrollview
...-UIView (contentview)
....-UIButton
....-UIButton
....-UIButton

... dan mengatur lebar tetap dan batasan tinggi untuk contentviewdan translatesAutoresizingMaskIntoConstraintspengaturan sesuai TechNote Apple. Tombol dan scrollview diatur menggunakan batasan. Ini mendapat scrollview scrolling (yay) tapi sayangnya, itu scroll terlalu jauh! Sejauh yang saya tahu, lebar gulir entah bagaimana digandakan dari apa yang saya atur tampilan konten ??? !!! ???

Saya mencoba pendekatan autolayout murni juga, baik dengan contentviewdan tanpa. Semua tampilan translatesAutoresizingMaskIntoConstraints=NO, kecuali untuk self.view. Tombol-tombol memiliki batasan lebar / tinggi tetap, dan disematkan ke keempat tepi scrollview. Tidak ada yang bergulir.

Jadi saya benar-benar bingung mengapa saya tidak bisa membuatnya bekerja dengan benar. Bantuan apa pun sangat dihargai, dan jika Anda memerlukan info lain, silakan tanyakan!

Screenshot DIPERBARUI dengan solusi - kendala buttonZ:

masukkan deskripsi gambar di sini

EDIT @ Jamie Forrest Jadi solusinya ternyata menjadi trailing constraint yang salah pada tombol terakhir. Alih-alih 6441, nilai yang saya tetapkan adalah negatif, -6441. Yang sulit adalah, ketika mengatur nilai di storyboard, ada dua opsi di Pin toolbar:

masukkan deskripsi gambar di sini

Nilai Kanvas Saat Ini negatif (mengarah ke tidak ada gulir), dan opsi di bawah ini positif (mengaktifkan gulir). Ini berarti saya tidak bodoh tapi setidaknya setengah buta saya kira. Meskipun, untuk pertahanan saya, bukankah agak mengganggu bahwa XCode tidak menunjukkan kesalahan untuk pengaturan "salah"?

EDITED LAGI Sekarang ini lucu ... mengubah nilai trailing dari -6441 (tanpa scroll) menjadi 6441 scroll yang diaktifkan. Tetapi teman lama saya "terlalu banyak konten" kembali, mengarah ke ukuran konten dua kali lebih besar dari yang seharusnya! Solusi untuk mendapatkan gulir konten yang benar adalah dengan mengatur batasan trailing menjadi NOL! Ini tidak jelas ketika bekerja di Storyboard tetapi melihat kode @Infinity James, itu yang seharusnya.

pengguna1459524
sumber
Di mana Anda menghitung / mengatur ukuran konten untuk tampilan gulir Anda? Mengacu pada upaya pertama Anda menggunakan contentView dan Anda mengatakan itu menggulir terlalu jauh.
Tim
2
Sejauh yang saya tahu, Anda tidak dapat mengatur contentSizesebuah UIScrollViewtata letak auto hanya menggunakan. Dan itu contentSizeyang menentukan seberapa banyak Anda dapat menggulir. Jadi Anda harus mengatur ini secara manual di suatu tempat pada akhirnya. Untuk selebihnya, Anda dapat menggunakan batasan tata letak untuk mengatur bingkai tampilan relatif satu sama lain.
Guillaume
@ Jeff, ukuran konten sudah diperbaiki, tidak pernah berubah. Saya mengatur ukuran konten di storyboard dengan memasukkan tinggi dan lebar yang benar untuk contentiview secara manual, dan saya menyematkan tinggi dan lebar dengan kendala di storyboard.
user1459524
Cetak konten AndaUkuran saat berjalan, lihat apakah itu cocok dengan nilai yang Anda masukan. ContentSize menentukan berapa banyak gulir terjadi, sehingga masalah dengan upaya pertama Anda adalah berkaitan dengan contentSize.
Tim
@Guillaume, jadi pendekatan "pure autolayout" tidak semurni itu? Tapi BAGAIMANA cara mengatur contentSize secara manual? Seperti yang saya sebutkan di atas, saya mengatur tinggi / lebar tampilan konten pada nilai tetap (di storyboard). Tapi itu menggulir terlalu jauh (2x).
user1459524

Jawaban:

68

Sulit untuk melihat nilai yang tepat dan pengaturan kendala Anda karena Anda menempelkannya di sini, jadi saya tidak yakin dari melihat tangkapan layar Anda di mana Anda salah.

Sebagai pengganti penjelasan tentang apa yang salah dalam pengaturan Anda, saya telah membuat proyek sampel dasar dengan hierarki tampilan yang sangat mirip dan pengaturan kendala dengan yang Anda jelaskan. Pengguliran horizontal berfungsi seperti yang diharapkan dalam proyek sampel, yang menggunakan pendekatan "Pure AutoLayout" yang dijelaskan Apple dalam Catatan Teknis .

Saya juga memiliki banyak masalah pada awalnya membuat Tata Letak Otomatis berfungsi UIScrollView. Kunci untuk membuatnya berfungsi adalah memastikan bahwa semua item dalam tampilan gulir, diambil bersama, memiliki kendala yang akhirnya menautkan ke semua sisi tampilan gulir dan yang berkontribusi pada sistem AutoLayout untuk dapat menentukan contentSize untuk tampilan gulir yang akan lebih besar dari bingkai. Sepertinya Anda mencoba melakukan itu dalam kode Anda, tetapi mungkin Anda memiliki beberapa kendala berlebihan di sana yang membuat contentSize terlalu kecil.

Juga perhatikan, seperti yang disebutkan lainnya, dengan AutoLayout dan UIScrollview, Anda tidak lagi mengatur contentSize secara eksplisit. Sistem AutoLayout menghitung contentSize berdasarkan kendala Anda.

Saya juga menemukan bab ebook ini sangat membantu dalam membuat saya mengerti bagaimana semua ini bekerja. Semoga semua ini bisa membantu.

Jamie Forrest
sumber
2
TERIMA KASIH atas proyek sampel! Ini bekerja, dan sambil melihatnya, saya tidak dapat menemukan perbedaan pada proyek saya pada awalnya! Saya menyalin pandangan ke proyek saya, mencurigai beberapa pengaturan selain kendala, tetapi terus bekerja. Ini membuat saya memperhatikan bahwa kendala trailing untuk tombol terakhir dalam proyek saya memiliki negatif - di depannya, sementara Anda memiliki nilai positif! Mengubah - ke positif mengaktifkan gulir! Ketika saya membuka Pin toolbar, ada dua pilihan: Gunakan nilai Canvas Sekarang, yang negatif, dan Scroll View (gunakan nilai saat ini) yang positif ...?!
user1459524
Ah iya. Nilai negatif sebenarnya akan membuat contentSize dari tampilan gulir lebih kecil, agar sesuai dengan fakta bahwa trailing edge harus berakhir sebelum tombol berakhir. Senang proyek sampel membantu!
Jamie Forrest
Itu banyak. Lihat jawaban saya yang diperbarui. Nilai trailing sebenarnya harus 0 (nol) tampaknya.
user1459524
6
Sungguh menyedihkan kita harus berbagi tangkapan layar alih-alih kode. Itu hanya karena apel mendorong pengembang untuk menggunakan pembangun daripada memberikan api yang lebih baik.
Vladimír Slavík
4
Benar-benar tidak intuitif. Pengembang harus menyia-nyiakan waktu berjam-jam untuk mencari tahu apa yang sedang terjadi dalam pikiran pencipta XCode.
Josh
49

LOL selamat datang di klub kebodohan. Saya salah satu pendiri. : D

Untuk pengguliran VERTIKAL : satu-satunya cara saya dapat membuatnya berfungsi (iOS 8, Xcode 6, dan autolayout murni) menambahkan batasan berikut untuk Tampilan Gulir saya (semua terkait dengan superview):

  • Lebar yang Sama
  • Ketinggian yang sama
  • Penyelarasan Center Y
  • Penjajaran Pusat X

Struktur saya:

  UIView
   - ScrollView
    - Subview
    - Subview
    - Subview
    - Subview
    - ...

Ini adalah hasil akhir:

Demo

Ini pengaturannya:

Mempersiapkan Layar penuh

Dan inilah proyeknya .

Semoga ini akan menyelamatkan seseorang dari AKAN TIDUR pukul 5 pagi. : D

backslash-f
sumber
Terima kasih banyak atas bantuannya! Bagaimana Anda mendapatkan subview dari tipe "subview" ?? Saya sedang melihat proyek Anda di Xcode 6.2, dan ia menyebut kotak kecil itu "Subview" dengan satu-satunya kendala adalah tingginya 63px.
Andrew K
1
Salam pembuka! "Subview" itu sebenarnya adalah UIVIew. Itu hanya sebuah nama ... Anda dapat mengetikkan apa saja di sana. Lihat gambar ini: cl.ly/image/291f1K2N0V3p Pada topik kendala, subview memiliki lebih dari sekadar batasan ketinggian. Periksa seluruh daftar kendala untuk tampilan tersebut di sini: cl.ly/image/3l061i123j2i
backslash-f
1
Saya masih belum bisa menjalankan scrolling - Saya perhatikan bahwa tampilan subview Anda "diklik" dalam proyek Anda. Setelah melakukan riset, sepertinya ini karena Anda menggunakan 'kelas ukuran'. Bagaimana ini mempengaruhi pengguliran? Apakah ada cara agar scrolling berfungsi tanpa menggunakan ini?
Andrew K
Juga, bagaimana Anda membuat superview Anda jauh lebih lama dari panjang default? Saya mencoba untuk menambahkan tombol yang akan muncul "di bawah flip" (atau dari layar) tapi jelas saya tidak bisa menambahkannya ke superview jika saya tidak dapat menarik dan menjatuhkannya ke superview karena itu tidak cukup besar.
Andrew K
1
setelah seharian mencari dan mencoba melakukan tata letak kebodohan ini, saya menemukan jawaban ini dan berfungsi pada percobaan pertama .. Terima kasih kawan .. Anda menghemat hari saya .. Saya berharap saya bisa memberikan ribuan suara untuk jawaban ini ..: )
Bobby Stenly
32

Contoh Mandiri Sederhana

Menilai dengan banyaknya suara pada pertanyaan dan rendahnya suara pada jawaban, orang tidak menemukan solusi yang mudah dimengerti dan cepat di sini. Biarkan saya mencoba menambahkannya. Proyek ini adalah contoh mandiri yang dilakukan sepenuhnya di Interface Builder. Anda harus bisa menyelesaikannya dalam 10 menit atau kurang. Kemudian Anda dapat menerapkan konsep yang Anda pelajari ke proyek Anda sendiri.

masukkan deskripsi gambar di sini

Pertanyaan awal bertanya tentang tombol gulir. Di sini saya hanya menggunakan UIViews tetapi mereka dapat mewakili tampilan apa pun yang Anda suka. Saya juga memilih pengguliran horizontal karena tangkapan layar storyboard lebih ringkas untuk format ini. Prinsipnya sama untuk pengguliran vertikal.

Konsep kunci

  • The UIScrollViewseharusnya hanya menggunakan satu subview. Ini adalah 'UIView' yang berfungsi sebagai tampilan konten untuk menampung semua yang ingin Anda gulir.
  • Buat tampilan konten dan orang tua tampilan gulir memiliki ketinggian yang sama untuk pengguliran horizontal. (Lebar yang sama untuk pengguliran vertikal)
  • Pastikan semua konten yang dapat digulir memiliki lebar yang ditetapkan dan disematkan di semua sisi.

Mulai proyek baru

Ini bisa menjadi aplikasi tampilan tunggal.

Storyboard

Dalam contoh ini kita akan membuat tampilan gulir horizontal. Pilih View Controller dan kemudian pilih Freeform di Size Inspector. Buat lebar 1,000dan tinggi 300. Ini hanya memberi kita ruang di storyboard untuk menambahkan konten yang akan bergulir.

masukkan deskripsi gambar di sini

Tambahkan Tampilan Gulir

Tambahkan a UIScrollViewdan sematkan keempat sisi ke tampilan akar pengontrol tampilan.

masukkan deskripsi gambar di sini

Tambahkan Tampilan Konten

Tambahkan UIViewsebagai subview ke tampilan gulir. Ini kuncinya. Jangan mencoba menambahkan banyak subview ke tampilan gulir. Cukup tambahkan satu UIView. Ini akan menjadi tampilan konten Anda untuk tampilan lain yang ingin Anda gulir. Sematkan tampilan konten ke tampilan gulir di keempat sisi.

masukkan deskripsi gambar di sini

Ketinggian yang sama

Sekarang di Outline Dokumen, Commandklik tampilan konten dan tampilan induk tampilan gulir untuk memilih keduanya. Kemudian atur ketinggian menjadi sama ( Controlseret dari Tampilan Konten ke Tampilan Gulir). Ini juga kuncinya. Karena kami menggulir secara horizontal, tampilan konten tampilan gulir tidak akan tahu seberapa tinggi seharusnya kecuali kami menyetelnya dengan cara ini.

masukkan deskripsi gambar di sini

catatan:

  • Jika kami membuat konten gulir secara vertikal, maka kami akan mengatur lebar tampilan konten agar sama dengan lebar induk tampilan gulir.

Tambah isi

Tambahkan tiga UIViews dan beri mereka semua batasan. Saya menggunakan margin 8 poin untuk semuanya.

masukkan deskripsi gambar di sini

Kendala:

  • Tampilan hijau: sematkan tepi atas, kiri, dan bawah. Buat lebar 400.
  • Tampilan merah: pin tepi atas, kiri, dan bawah. Buat lebar 300.
  • Tampilan ungu: pin keempat tepi tepi. Buat lebar apa pun ruang yang tersisa (268 dalam hal ini).

Mengatur batasan lebar juga merupakan kunci sehingga tampilan gulir tahu seberapa lebar tampilan kontennya.

Jadi

Itu saja. Anda dapat menjalankan proyek Anda sekarang. Itu harus berperilaku seperti gambar bergulir di bagian atas jawaban ini.

Untuk pengguliran vertikal, cukup tukar semua arah lebar dan tinggi dalam contoh ini (teruji dan berfungsi).

Pelajaran lanjutan

Suragch
sumber
9

ContentSize secara implisit diatur dengan menerapkan batasan di dalam UIScrollView.

Sebagai contoh, apakah Anda memiliki UIScrollView di dalam UIView maka akan terlihat seperti ini (karena saya yakin Anda tahu):

    UIView *containerView               = [[UIView alloc] init];
    UIScrollView *scrollView            = [[UIScrollView alloc] init];
    [containerView addSubview:scrollView];
    containerView.translatesAutoresizingMaskIntoConstraints = NO;
    scrollView.translatesAutoresizingMaskIntoConstraints    = NO;
    NSDictionary *viewsDictionary       = NSDictionaryOfVariableBindings(containerView, scrollView);

    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|"
                                                                          options:kNilOptions
                                                                          metrics:nil
                                                                            views:viewsDictionary]];
    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
                                                                          options:kNilOptions
                                                                          metrics:nil

Itu akan mengatur scrollView untuk mengisi ukuran containerView (jadi containerView harus berukuran tertentu).

Anda kemudian dapat menyesuaikan contentSize dari UIScrollView dengan secara implisit mengaturnya agar cukup besar untuk menahan tombol-tombol seperti ini:

    UIButton *buttonA                   = [[UIButton alloc] init];
    UIButton *buttonB                   = [[UIButton alloc] init];
    UIButton *buttonC                   = [[UIButton alloc] init];
    [scrollView addSubview:buttonA];
    [scrollView addSubview:buttonB];
    [scrollView addSubview:buttonC];
    buttonA.translatesAutoresizingMaskIntoConstraints       = NO;
    buttonB.translatesAutoresizingMaskIntoConstraints       = NO;
    buttonC.translatesAutoresizingMaskIntoConstraints       = NO;

    viewsDictionary                     = NSDictionaryOfVariableBindings(scrollView, buttonA, buttonB, buttonC);

    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[buttonA]-|"
                                                                       options:kNilOptions
                                                                       metrics:nil
                                                                         views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[buttonA]-[buttonB]-[buttonC]-|"
                                                                       options:NSLayoutFormatAlignAllBaseline
                                                                       metrics:nil
                                                                         views:viewsDictionary]];
Infinity James
sumber
Jadi, saya mengatur batasan antara scrollView dan tombol, dan bukan containerView dan tombol? Saya pikir itu tentang satu-satunya perbedaan yang saya pakai antara kode Anda dan apa yang saya lakukan melalui storyboard sekarang.
user1459524
Saya baru menyadari setelah membaca kedua bahwa Anda sedang mengatur tampilan CONTAINER dan bukan CONTENTview. Berdasarkan kode Anda, saya telah membuat ulang semuanya persis di storyboard, dan itu tidak bergulir. Saya akan mengedit pertanyaan saya dengan beberapa tangkapan layar.
user1459524
1
Jadi ternyata usaha saya untuk membuat ulang kode di storyboard tidak 100% benar. Nilai trailing untuk tombol terakhir harus benar-benar nol, mencerminkan H: | - [buttonA] - [buttonB] - [buttonC] - | yang tidak terlalu jelas ketika bekerja di storyboard (atau setidaknya bukan untuk saya) tetapi sekarang setelah fakta tampaknya sepele. Saya suka autolayout tetapi hal-hal kecil itu membuat Anda ...
user1459524
Apa yang @ user1459524 sebutkan adalah masalah bagi saya. Tampak bawah saya adalah tombol dan batasan bawah adalah -32 oleh IB. Saya menetapkan itu ke 0 dan diperbarui di IB menjadi Bottom Space ke: superview. Ini akan berhasil, juga tampaknya selama Anda berada di sisi positifnya. Sepertinya itu mungkin bug dengan IB. Semoga itu bisa membantu orang lain. Saya juga menghapus semua tampilan dan rewired yang membantu ketika mencoba meletakkan ini saya temukan dan biasanya tidak butuh waktu lama.
Michael
8

Ada begitu banyak pertanyaan tentang penggunaan AutoLayout dengan UIScrollView, titik kunci yang kami abaikan adalah bahwa pandangan bagian dalam UIScrollView membuat kendala terhadap Tampilan Konten tetapi bukan UIScrollView itu sendiri. Lihat Catatan Teknis TN2154 , Anda dapat menemukan:

Kelas UIScrollView menggulir kontennya dengan mengubah asal batasnya. Untuk membuat ini bekerja dengan Tata Letak Otomatis, tepi atas, kiri, bawah, dan kanan dalam tampilan gulir sekarang berarti tepi tampilan kontennya.

Gambar berikut akan menggambarkan bahwa: masukkan deskripsi gambar di sini

Anda dapat menemukan ruang trailing adalah 500 poin, jika batasan dibuat untuk UIScrollView, tampilan akan dilewatkan dan harus memperbarui bingkainya. Namun, tidak ada peringatan dan tidak ada kesalahan. Karena semua kendala bertentangan dengan tampilan konten.

UIScrollView akan menghitung ukuran tampilan konten sesuai dengan batasan tampilan dalam. (Sebagai contoh, ukuran konten: lebar = 100 (ruang depan) + 200 (lebar tampilan) + 500 (ruang tambahan), tinggi = 131 (spasi atas) + 200 (tinggi) + 269 (spasi bawah)

Cara menambahkan batasan untuk tampilan di UIScrollView:

  1. Pencitraan posisi tampilan dalam tampilan konten.
  2. Tambahkan jarak atas, kanan, bawah, kiri ke tepi tampilan konten, di samping itu, juga lebar dan tinggi tampilan ini.

Dan semua itu dilakukan.

Cara mudah untuk menangani AutoLayout dengan scrollview adalah dengan menambahkan tampilan kontainer yang berisi semua subview dalam tampilan gulir.

Kesimpulan: titik kunci untuk memahami AutoLayout dengan UIScrollView adalah tampilan dalam membuat kendala terhadap tampilan konten tetapi bukan UIScrollView itu sendiri.

kode contoh terlampir

Danyun Liu
sumber
5

Solusi berikut ini berfungsi untuk saya untuk scrollView dengan autolayout dan tanpa contentSize :

  1. Seret dan lepaskan scrollView ke viewController dan terapkan kendala apa pun untuk menutupi ruang yang Anda inginkan.
  2. Seret dan letakkan UIView di dalam scrollView dan buat itu menutupi seluruh ruang scrollView dan terapkan kendala menjadi ruang atas, kiri, kanan, bawah dari scrollView.
  3. Atur tinggi (dan lebar jika pengguliran horizontal diperlukan) dari tampilan dalam sesuai kebutuhan pengguliran. Bagian ini juga dapat dilakukan dari kode jika diperlukan.
  4. Sangat penting . Setelah Anda mengatur ketinggian ke beberapa nilai besar di titik (3), kembali ke titik (2) dan pastikan untuk mengatur nilai atas, kiri, kanan, bawah kembali ke nol karena Xcode mungkin telah mengubahnya untuk Anda ketika Anda memaksa mengubah ketinggian di (3).

Dan kamu sudah selesai. Sekarang, Anda dapat menambahkan sejumlah kontrol pada tampilan ini dan menerapkan batasan yang relevan satu sama lain (yang tampaknya tidak berfungsi tanpa tampilan ini). Jika Anda tidak ingin menggunakan tampilan ini maka Anda harus menerapkan batasan untuk setiap kontrol yang terkait dengan scrollView (tidak terkait satu sama lain).


Tip luar biasa ..............

Sangat penting . Katakanlah untuk kejelasan UIScrollView adalah 1000 lebar dan 100 tinggi. (Sebenarnya biasanya nilai-nilai ini akan dinamis, tentu saja, tergantung pada lebar perangkat dll. Tapi untuk sekarang katakan saja 1000 lebar dan 100 tinggi.) Katakanlah Anda sedang melakukan gulir horizontal. Jadi, letakkan UIView di dalam UIScrollView. (Itulah "tampilan konten".) Atur keempat batasan tampilan konten di bagian atas, bawah, depan, belakang, hingga tampilan gulir. Buat semuanya nol bahkan jika itu tampak salah. Atur tinggi konten UIView menjadi 100 dan lupakan itu. Sekarang: Anda ingin menggulir secara horizontal, jadi atur lebar tampilan konten menjadi misalkan 1225.

Perhatikan bahwa lebar tampilan konten sekarang 225 lebih besar dari lebar tampilan gulir induk. Tidak apa-apa: pada kenyataannya, Anda HARUS melakukan itu. Catat itu

... Anda TIDAK mengatur lebar jejak ke negatif 225 ...

Anda akan berpikir Anda harus "mencocokkan" lebarnya seperti biasanya . Tetapi jika Anda melakukan itu, itu tidak akan berhasil sama sekali.

Anda harus mengatur angka awal dan akhir menjadi NOL , tidak pernah negatif (meskipun lebarnya "lebih besar")

Menariknya, Anda benar-benar dapat mengatur angka awal / akhir pada nilai positif apa pun (coba katakan "50") dan itu memberi Anda semacam margin bouncing. (Sering terlihat hebat: coba saja.) Nilai negatif apa pun di kedua ujung akan "diam-diam pecah".

Perhatikan bahwa, seringkali Xcode (seperti 7.3.1),

akan 'membantu' mengatur nilai-nilai itu untuk Anda ke angka negatif!

karena mencoba untuk menghitungnya secara otomatis untuk Anda. Jika demikian itu akan diam-diam pecah. Atur keempat nilai menjadi nol pada instance pertama. Dan atur lebar tampilan konten jauh lebih luas daripada "1000" dalam contoh.


Diedit: Saya menggunakan UITableView alih-alih UIScrollView untuk sebagian besar kebutuhan saya. TableView menurut saya jauh lebih fleksibel dan dinamis.

zeeawan
sumber
Ini sebenarnya jawaban terbaik di sini. Terima kasih!
Fattie
4

Saya menganggap Anda mengalami masalah dengan contentSize. Lihat posting blog ini tentang cara menangani contentSizeketika menggunakan pendekatan AutoLayout "murni". Intinya adalah bahwa kendala Anda secara implisit menentukan ukuran konten. Anda TIDAK PERNAH mengaturnya secara eksplisit saat menggunakan AutoLayout. Saya telah melampirkan proyek contoh di akhir posting blog untuk menunjukkan cara kerjanya

Edward Huynh
sumber
3

Ada bagian dalam catatan teknologi yang mungkin Anda lihat. Anda secara implisit dapat mengatur ukuran konten tampilan gulir menggunakan batasan yang ditetapkan pada tepi tampilan gulir.

Ini contoh sederhana. Buat storyboard dengan satu tampilan, yang memiliki satu tampilan gulir. Tetapkan batasan tampilan gulir agar sesuai dengan ukuran tampilan yang Anda gunakan.

Di dalam tampilan gulir itu tambahkan satu tampilan. Secara eksplisit mengatur ukuran tampilan yang menggunakan kendala (dan pastikan ukuran lebih besar dari tampilan gulir).

Sekarang tambahkan empat kendala lagi ke tampilan dalam yang mengunci empat tepi tampilan dalam ke tampilan gulir induknya. Keempat kendala tersebut akan menyebabkan ukuran konten meluas untuk mengakomodasi tampilan dalam.

Jika Anda memiliki beberapa tampilan yang ingin Anda tambahkan ke tampilan gulir, misalnya diletakkan secara horizontal, Anda akan mengunci sisi kiri subview pertama ke kiri tampilan gulir, mengunci subview satu sama lain secara horizontal, dan kanan sisi sub tampilan terakhir ke sisi kanan tampilan gulir. Kendala-kendala itu akan memaksa ukuran konten tampilan gulir untuk diperluas untuk mengakomodasi semua subview dan kendala mereka.

Travis
sumber
3

Jika pertanyaan Anda adalah "Bagaimana cara saya menempatkan sekelompok UITextFields dalam UIScrollView yang bergulir secara vertikal sehingga mereka keluar dari keyboard ketika mereka memiliki fokus", jawaban terbaik adalah:

Jangan.

Gunakan UITableViewController dengan sel statis sebagai gantinya.

Anda mendapatkan perilaku scroll-out-of-the-way ini secara gratis, DAN semua inset konten Hanya Bekerja jika pengontrol tampilan Anda ditampilkan di dalam UINavigationController.

Robert Atkins
sumber
3

Anda harus mengatur tata letak Anda seperti ini
ViewControllerViewberisi ScrollView, ScrollViewmengandung ContainerView, ContainerViewmengandung 2Labels
masukkan deskripsi gambar di sini

Kemudian ikuti 3 langkah untuk membuat ScrollViewgulir kaleng Anda

  1. Atur ScrollViewpin (atas / kanan / bawah / kiri) keViewControllerView
    • Atur ContainerViewpin (atas / kanan / bawah / kiri) keScrollView
    • Setel Horizontally in Container( jangan disetel Vertically in Container)
    • Label1pin ( atas / kanan / kiri) keContainerView
    • Label1pin (kanan / kiri / bawah ) ke ContainerViewdan atas keLabel1

masukkan deskripsi gambar di sini

HERE adalah proyek demo

Semoga bantuan ini

Phan Van Linh
sumber
1

Pendekatan autolayout murni berfungsi dengan baik tetapi sulit untuk diatur jika Anda bermigrasi dari non-autolayout. Saya sudah melakukannya beberapa kali sekarang dan saya punya beberapa tips umum:

  • Mulai dari yang kecil: meskipun itu berarti membuat ulang tampilan papan cerita Anda, mulailah dengan hanya beberapa elemen dan bangun pandangan Anda secara perlahan, pastikan untuk menguji bahwa pengguliran berhasil setelah menambahkan beberapa elemen.
  • Matikan translationsAutoresizingMaskIntoConstraints pada semuanya: ini selalu menjadi penyebab konflik kendala bagi saya.
  • Setel batasan UIScrollView Anda dengan benar: pastikan tampilan gulir terhubung di semua sisi ke tampilan induk, jika tidak, ia tidak akan berkembang sama sekali.
Nick
sumber
1

Setelah beberapa waktu menangani masalah ini, saya akhirnya menemukan solusi. Saya bekerja dengan storyboard ukuran kelas universal (600x600). Saya membuat UIView (contentView) ukuran scrollView dan membuat batasan untuk Top, Bottom, Leading dan Trailing ke scrollView. Lalu saya memotong ukuran secara manual dari contentView ke 600x600. Storyboard berhenti berusaha mengubah ukuran segalanya dan saya bisa bekerja tetapi tampilan tampak mengerikan pada perangkat nyata atau simulator. Saya membuat 2 outlet kendala ukuran terpotong ini.

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewWidthConstraint; 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewHeightConstraint;

Kemudian di viewDidLoad

CGSize viewSize = self.view.frame.size;
self.contentViewWidthConstraint.constant = viewSize.width;
self.contentViewHeightConstraint.constant = viewSize.height;

Bagus sekali.

Cristian Pena
sumber
1

Saya menghabiskan waktu berhari-hari untuk mencari solusi tentang cara menggunakan AutoLayout melihat Scrollview tertanam, untuk memusatkan scrollview di layar yang terlihat, yang bekerja di semua dimensi perangkat / layar serta dengan rotasi layar.

Saya menghabiskan waktu berhari-hari mencoba melakukannya dengan Autolayout saja, dan menjadi dekat tetapi tidak pernah cukup dekat. Jadi pada akhirnya saya harus menambahkan 3 baris kode per layar juga, di viewDidLoad.

Lihat solusi di bawah ini:

  1. Buat scrollview dan isi dengan objek apa pun yang Anda inginkan
  2. Aktifkan tata letak otomatis
  3. Kemudian Arahkan ScrollView secara Vertikal dan Horizontal Pusat ScrollView
  4. Pilih Lihat dan kemudian 'Tambah kendala yang hilang' - ini kemudian melakukan tugasnya
  5. Hasilnya adalah banyak kendala yang dihasilkan. Ada 2 yang baru dibuat untuk tampilan: 'Horizview scrollview to View' dan 'Scrollview space to view' atau sebaliknya.
  6. Hapus 'Horizview scrollview to View' sehingga Anda sekarang memiliki 3 kendala pada View. 2 untuk memasuki scrollview dalam tampilan dan yang mengatur ruang vertikal antara scrollview dan view
  7. Sekarang tautkan kendala Vert ke kode Anda dengan mengklik dan Ctrl menyeretnya ke file header dan membuat NSOayletConstraint IBOutlet (saya sebut mine constraintVertVtoSV)
  8. Sekarang pergi ke file .m dan tambahkan baris kode ini ke viewDidLoad (bermain dengan jumlah padding untuk mendapatkan vert centering yang benar)

    if (IPAD)

    {self.constraintVertVtoSV.constant = 150.0; }

  9. ini sekarang harus berjalan di semua perangkat dan dipusatkan dengan benar dan masih gulir dengan benar.

Orang
sumber
1

Jika seperti saya, Anda hanya menggunakan konten statis tanpa kendala di dalam subview, seperti yang dapat Anda lakukan seperti ini:

override func viewDidLayoutSubviews() {
    scrollView.contentSize = CGSizeMake(320, 800)
}
Antzi
sumber
1

Masalah serupa yang saya alami hari ini dengan iOS 8.4, Xcode 6.4

Ada tampilan yang berisi tampilan gulir, yang berisi contentView (UIView) yang berisi subview.

Semuanya tata letak otomatis di mana-mana. Tepi scrollview disematkan ke tepi tampilan induk dengan kendala. Tepi tampilan konten disematkan ke tepi tampilan gulir dengan kendala.

Awalnya tampilan konten akan menolak ukuran karena lebar penuh dari tampilan gulir. Saya harus menambahkan batasan tambahan pada tampilan konten agar lebarnya sesuai dengan tampilan gulir induk. Atau saya bisa mengatur batasan contentView.centerX == scrollView.centerX. Salah satu dari mereka selain menyematkan tepi tiba-tiba membuat ukuran konten terlihat dengan benar.

// Either one of these additional constraints are required to get autolayout to correctly layout the contentView. Otherwise contentView size is its minimum required size
scrollView.addConstraint(NSLayoutConstraint(item: contentView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1.0, constant: 0))
scrollView.addConstraint(NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: scrollView, attribute: .Width, multiplier: 1.0, constant: 0.0))

Menyematkan tepi tampilan konten ke tampilan gulir menggunakan batasan visual dari formulir,

let cvConstraints = ["H:|[contentView]|", "V:|[contentView]|"]

Saya menggunakan rutin untuk beralih melalui array dan menambahkannya ke scrollView.

David
sumber
1

Saya menghadapi masalah yang sama. Saya menetapkan setiap kendala dan selalu bertanya-tanya mengapa masih mengubah ukuran beberapa subview. Solusi saya adalah mengatur clipsToBounds ke YES.

i89
sumber
1

Dengan cepat Anda dapat menggunakan solusi kerja ini.

Pengaduan

ScrollView: Leading, Trailing, Top, Bottom = Superview

ContentView: Memimpin, Mengikuti, Atas, Bawah = ScrollView. Tinggi tetap / relatif terhadap konten.

Anda dapat mengatur batasan lebar (contentView) untuk sama dengan tampilan tampilan gulir, tetapi pilih hapus hapus saat membangun karena Anda akan menambahkan kendala itu secara terprogram. Ini hanya agar IB tidak mengeluh dengan peringatan.

extension UIView {

    func setupContentViewForViewWithScroll(contentView vwContent : UIView) {
        //Set constraint for scrollview content
        let constraint = NSLayoutConstraint(item: vwContent, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.bounds.size.width)
        vwContent.addConstraint(constraint)
        self.layoutSubviews()
    }

}

Dan di View Controller viewDidLayoutSubviewssaya sebut saja metode ini:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.view.setupContentViewForViewWithScroll(contentView: vwContent)
}
Ibrahim Yildirim
sumber
0

Saya tahu ini adalah solusi awam dan bukan apa yang disarankan Apple dalam dokumen, tetapi ini berfungsi dua kali bagi saya, dengan konten yang berbeda dan dapat diatur dengan sangat cepat: Di controller tampilan storyboard masukkan UIView. Dalam UIView masukkan Table View, Dynamic, 0 sel prototipe, Style Plain atau Dikelompokkan. Dalam Tampilan Tabel, masukkan Tampilan Gulir, dalam konten tampilan Lihat Gulir. Itu, tidak ada pengaturan di controller tampilan kustom.

Rinaldo
sumber