Ambiguitas Ukuran Konten yang Dapat Digulir UIScrollView

510

Rekan-rekan pengembang, saya mengalami masalah dengan AutoLayout di Interface Builder (Xcode 5 / iOS 7). Ini sangat mendasar dan penting, jadi saya pikir semua orang harus tahu cara kerjanya dengan benar. Jika ini adalah bug di Xcode, itu adalah bug yang kritis!

Jadi, setiap kali saya memiliki hierarki tampilan seperti ini, saya mengalami masalah:

>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)

UIScrollView memiliki kendala solid, misalnya, 50 px dari setiap sisi (tidak ada masalah). Kemudian saya menambahkan batasan Space Top ke label UIL (tidak ada masalah) (dan saya bahkan dapat menyematkan tinggi / lebar label, tidak mengubah apa pun, tetapi harus tidak perlu karena ukuran intrinsik Label)

Masalahnya dimulai ketika saya menambahkan batasan trailing ke UILabel:

Misalnya, Trailing Space ke: Superview Equals: 25

Sekarang dua peringatan terjadi - dan saya tidak mengerti mengapa:

A) Ambiguitas Ukuran Konten yang Dapat Digulir (Scroll View memiliki tinggi / lebar konten yang dapat digulir)

B) Tampilan salah tempat (Label Diharapkan: x = -67 Sebenarnya: x = 207

Saya melakukan contoh minimal ini dalam proyek baru yang dapat Anda unduh dan saya lampirkan tangkapan layar. Seperti yang dapat Anda lihat, Interface Builder mengharapkan Label untuk duduk di luar batas UIScrollView (persegi panjang berwarna oranye). Memperbarui bingkai Label dengan Resolve Issues Tool memindahkannya ke sana.

Harap dicatat: Jika Anda mengganti UIScrollView dengan UIView, perilaku seperti yang diharapkan (bingkai Label sudah benar dan sesuai dengan kendala). Jadi sepertinya ada masalah dengan UIScrollView atau saya kehilangan sesuatu yang penting.

Ketika saya menjalankan Aplikasi tanpa memperbarui bingkai Label seperti yang disarankan oleh IB, itu diposisikan dengan baik, tepat di tempat seharusnya dan UIScrollView dapat digulir. Jika saya DO memperbarui bingkai Label tidak terlihat dan UIScrollView tidak menggulir.

Bantu aku Obi-Wan Kenobi! Mengapa tata letak ambigu? Mengapa tampilan salah tempat?

Anda dapat mengunduh proyek sampel di sini dan mencoba jika Anda dapat mengetahui apa yang terjadi: https://github.com/Wirsing84/AutoLayoutProblem

Ilustrasi masalah di Interface Builder

Wirsing
sumber
8
Coba letakkan UILabel dalam tampilan konten, lalu atur tepi trailing label ke tampilan konten (UIView biasa). Video ini dapat sangat membantu Anda: youtube.com/watch?v=PgeNPRBrB18&feature=youtu.be
erdekhayser
1
Video bagus tapi tidak memperbaiki peringatan untuk saya. :(
Tuan Rogers
Terima kasih banyak untuk videonya - ada (agak mengejutkan) saya cukup banyak belajar darinya! Namun, ketika saya menggabungkan pengetahuan video dengan stackoverflow.com/questions/18953617/... saya dapat memperbaiki peringatan. Pertanyaan yang tersisa adalah: Bagaimana cara membuat ukuran scrollView contentView hanya sebesar yang diperlukan?
Wirsing
Lihatlah video ini . Ini menunjukkan cara menggunakan UIScrollLayout dan autolayout dengan XCode 5 / iOS 7.
jaxvy
Saran saya jangan gunakan UIScrollViewsecara langsung. Alih-alih menggunakan UICollectionViewatau UITableViewsebanyak mungkin, kebanyakan setiap hal adalah mungkin dengan elemen ini dan juga memberikan kesederhanaan, keterbacaan dan penggunaan kembali !!!
SPatel

Jawaban:

1093

Jadi saya hanya memilah seperti ini:

  1. Di dalam UIScrollView add a UIView(kita bisa menyebutnya contentView);

  2. Dalam hal ini contentView, atur margin atas, bawah, kiri dan kanan ke 0 (tentu saja dari yang scrollViewmana adalah superView); Atur juga sejajarkan pusat secara horizontal dan vertikal ;

Selesai .

Sekarang Anda dapat menambahkan semua pandangan Anda di dalamnya contentView, dan semua contentSizeitu scrollViewakan secara otomatis diubah ukurannya sesuai dengan contentView.

Memperbarui:

Beberapa kasus khusus dicakup oleh video ini yang diposting oleh @Sergio di komentar di bawah.

Matteo Gobbi
sumber
33
Hampir sempurna, kecuali bahwa scrollview tidak dapat lagi menebak panjang konten Anda dan mengubah ukurannya sesuai itu contentSize agar sesuai dengan objek di dalamnya. Saya memiliki tampilan tabel di dalam contentView yang ketinggiannya berubah (melalui kendala) dan scrollview tidak memungkinkan saya untuk menggulir.
CyberMew
28
Mungkin video ini dapat membantu mengatasi semua masalah yang tersisa.
Sergio
46
ini tidak membuatnya gulir tho.
dorian
2
@MatteoGobbi Itu dia! Itu berhasil! Sedang bergumul dengan masalah seperti ini dari scrollView autoLayout madness selama 2 hari .... Terima kasih kawan !!!
polo987
56
Bagi siapa pun yang menghadapi masalah dengan ScrollView karena tidak dapat digulir, pengaturan bagian bawah dan pusat perataan contentView secara vertikal dibatasi dengan prioritas rendah telah membantu saya!
jimmy0251
98

Kesalahan ini memakan waktu beberapa saat untuk melacak, awalnya saya mencoba menyematkan ukuran ScrollView tetapi pesan kesalahan dengan jelas mengatakan "ukuran konten". Saya memastikan semua yang saya sematkan dari atas ScrollView juga disematkan ke bawah. Dengan begitu ScrollView dapat menghitung tinggi kontennya dengan menemukan ketinggian semua objek & batasan. Ini memecahkan ketinggian konten yang ambigu, lebarnya sangat mirip ... Awalnya saya memiliki banyak hal yang berpusat pada ScrollView, tetapi saya juga harus menyematkan objek ke sisi ScrollView. Saya tidak suka ini karena iPhone6 ​​mungkin memiliki layar lebih lebar tetapi akan menghapus kesalahan 'ambiguous content width'.

self.name
sumber
31
Terima kasih atas jawaban Anda! Jika saya memahami Anda dengan benar, Anda dapat menghapus kesalahan dengan menyematkan setiap dan semua subview di ScrollView ke atas dan bawah. Namun, ini tidak perlu. Anda hanya perlu memastikan bahwa ada cara untuk membuat garis kendala terus menerus dari atas ke bawah scrollview. [-XXX] Saya harap itu bisa dimengerti;>
Wirsing
1
Bagaimana cara memperbaiki masalah jika tampilan memiliki variabel hight? Bagaimana cara saya mengatur kendala sehingga scrollview dapat menghitung ukuran?
hashier
2
'Anda hanya perlu memastikan bahwa ada cara untuk membuat garis kendala terus menerus dari atas ke bawah scrollview' <- terima kasih untuk kalimat itu
Adam Waite
3
Apa yang membantu saya adalah memastikan tampilan gulir disematkan ke superview dan bukan panduan tata letak atas atau bawah. Saya menghapus kendala untuk panduan tata letak bawah dan pergi melalui menu bukannya pembangun antarmuka. Editor -> Pin -> Bottom Space to Superview.
Alberto Lopez
2
Jika Anda ingin lebar scrollview mengikuti lebar layar ponsel Anda atau elemen lain di UI Anda (seperti UIView yang mengandung), Anda perlu mengatur "sama lebar" di atasnya dengan menggunakan elemen lain yang berada di luar scrollview untuk mengukur.
Departamento B
89

Xcode 11+

Cara paling sederhana menggunakan autolayout:

  1. Tambahkan UIScrollViewdan sematkan 0,0,0,0ke superview (atau ukuran yang Anda inginkan)
  2. Tambahkan UIViewdi ScrollView, sematkan 0,0,0,0ke semua 4 sisi dan pusatkan horizontallydan vertically.
  3. Pada inspektur ukuran, ubah bottomdan align center Yprioritaskan menjadi 250. (untuk perubahan gulir horizontal trailingdan align center X)
  4. Tambahkan semua tampilan yang Anda butuhkan ke tampilan ini. Jangan lupa untuk mengatur batasan bawah pada tampilan terendah.
  5. Pilih UIScrollView, pilih inspektur ukuran dan batalkan pilihan Content Layout Guides.
Norđe Nilović
sumber
1
Saya tidak dapat mengatur tinggi konten scrollview tetapi berfungsi. :)
Blind Ninja
2
Petunjuk: menurut saya ini hanya berfungsi, jika saya menghapus center secara horizontal dan vertikal dan menggantinya dengan lebar yang sama (scrollView + view inside scrollView) DAN menambahkan ketinggian berdasarkan pada konten, yang berarti elemen terakhir dari tampilan memerlukan batasan bawah. Lihat di sini untuk informasi lebih lanjut: stackoverflow.com/a/54577278/5056173
Sean Stayns
1
Sean, saya menggunakan ini secara harfiah setiap hari dan saya tidak pernah punya masalah dengan pendekatan ini ketika datang ke scrollview scroll vertikal dan horizontal. Mungkin Anda lupa memberi batasan bawah pada elemen terendah / terakhir. Tanpa itu, ini tidak akan berhasil.
đorđe Nilović
7
Poin nomor 4 - kalimat kedua adalah yang besar.
Nitish
2
jawaban ini sangat cocok untuk saya
satvinder singh
63

Ini adalah jawaban untuk pertanyaan yang saya jawab sendiri UIScrollView + Tampilan Tengah + Ukuran Konten yang Dapat Digulir + ukuran iPhone yang banyak .

Tapi itu sepenuhnya menutupi kasus Anda juga!

Jadi, inilah keadaan awal untuk kasus paling sederhana:

  1. scrollView dengan 0 batasan pada semua sisi
  2. Tombol berpusat Horisontal dan Vertikal dengan batasan Lebar dan Tinggi tetap
  3. Dan, tentu saja - peringatan Has ambiguous scrollable content width dan Has ambiguous scrollable content height.

1

Yang harus kita lakukan adalah:

  • Tambahkan 2 kendala tambahan, misalnya "0" untuk trailing dan / atau ruang bawah untuk tampilan kami (lihat contoh pada tangkapan layar di bawah).

Penting: Anda harus menambahkan trailing dan / atau batasan bawah . Bukan "terkemuka dan teratas" - ini tidak berhasil!

2

Anda dapat memeriksanya di proyek contoh saya , yang menunjukkan cara memperbaiki masalah ini.

PS

Menurut logika - tindakan ini harus menyebabkan "kendala yang saling bertentangan". Tapi tidak!

Saya tidak tahu mengapa ia bekerja dan bagaimana Xcode mendeteksi kendala mana yang lebih diprioritaskan (karena saya tidak menetapkan prioritas untuk kejelasan kendala ini). Saya akan berterima kasih jika seseorang menjelaskan, mengapa itu bekerja di komentar di bawah ini.

pencukur langit
sumber
Tip yang bagus! Saya akhirnya hanya membuat batasan untuk tepi bawah dan menetapkan prioritas ke sedang atau rendah
Dean
Wow! Ini serius tidak masuk akal tetapi berfungsi! Terima kasih! Item terakhir yang saya miliki dalam pandangan saya, saya menetapkan batasan bawah 0, dan BANG. Akhirnya berhasil.
Jakob Hviid
60

Xcode 11+, Swift 5

Jika Anda bertanya-tanya mengapa semua jawaban tidak berfungsi lagi, pastikan Anda telah menyematkan tampilan konten (yang Anda masukkan ke dalam tampilan gulir) ke Panduan Tata Letak Konten dari tampilan gulir dan BUKAN ke Panduan Tata Letak Bingkai.

Tepi tampilan konten (depan, belakang, atas, bawah) tidak boleh disematkan seperti memimpin pada gambar - ke Panduan Tata Letak Bingkai

Tidak seperti ini

tapi seperti ini - ke Panduan Tata Letak Konten.

Pilih Panduan Tata Letak Konten dari dropdown

masukkan deskripsi gambar di sini

Dan kemudian sebagian besar jawaban akan bekerja untuk Anda.

Pendekatan paling sederhana sekarang adalah seperti ini:

  1. Letakkan tampilan gulir di tampilan root
  2. Sematkan semua sisi tampilan gulir ke superview
  3. Ambil UIView lain (akan menyebutnya tampilan konten) dan masukkan ke dalam tampilan gulir
  4. Sematkan semua sisi tampilan konten untuk menggulir Panduan Tata Letak Konten tampilan
  5. Sematkan lebar tampilan konten agar sama dengan Panduan Layout Bingkai tampilan gulir
  6. Perbaiki ketinggian tampilan konten dengan cara apa pun yang Anda inginkan (saya hanya menggunakan batasan ketinggian konstan pada contoh di bawah)

Secara keseluruhan struktur Anda dalam implementasi paling sederhana akan terlihat seperti ini

masukkan deskripsi gambar di sini

Ingin tahu
sumber
@WantToKnow Tidak perlu mengambil batasan untuk ketinggian, cukup ubah prioritasnya ke rendah (250)
Reckoner
Xcode 11+, Swift 5. Menurut jawaban @WantToKnow, saya memecahkan masalah saya, saya menyiapkan [video] [1] dan [kode] [2] [1]: youtube.com/watch?v=qMrH5_Yj5hM [2]: github.com/AhmAbdallah/CustomCollectionView
Ahmed Abdallah
1
Ini jawaban yang bagus, terima kasih.
Constantine
1
Ini adalah jawaban yang benar. Terima kasih.
Vincent Joy
Ini bekerja untuk saya hanya ketika saya menambahkan batasan bawah ke elemen terakhir dari tampilan konten
D.Zotov
49

Anda harus membuat UIViewsubview UIScrollViewseperti yang dijelaskan di bawah ini:

  • UIViewController
  • UIView 'Tampilan Utama'
    • UIScrollView
      • UIView 'Tampilan Kontainer'
        • [Konten Anda]

Langkah kedua adalah membuat UIScrollViewkendala. Saya melakukan ini dengan batasan atas, bawah, depan dan belakang untuk superView-nya.

Selanjutnya saya menambahkan kendala untuk wadah UIScrollViewdan di sinilah masalahnya dimulai. Saat Anda meletakkan batasan yang sama (atas, bawah, depan dan belakang) Storyboard memberikan pesan peringatan:

"Memiliki lebar konten yang dapat digulir ambigu" dan "Memiliki tinggi konten yang dapat digulir ambigu"

Lanjutkan dengan kendala yang sama di atas, dan tambahkan saja kendala Equal Heightdan Equal Widthke Tampilan Kontainer Anda sehubungan dengan Tampilan Utama dan bukan untuk Anda UIScrollView. Dengan kata lain batasan Container View terkait dengan UIScrollViewsuperview.

Setelah itu Anda tidak akan memiliki peringatan di Storyboard Anda dan Anda dapat terus menambahkan kendala untuk subview Anda.

Thiago Monteiro
sumber
2
Setuju - Saya pikir menambahkan tampilan kontainer adalah yang terbaik, solusi yang paling dapat dikelola.
Andrew Ebling
1
Solusi ini akan berfungsi ketika Anda tidak memiliki bilah navigasi untuk dikelola.
Leena
26

Saya memiliki masalah yang sama. Hapus centang pada kotak ini. Karena Anda mengatur ukuran konten dalam kode. masukkan deskripsi gambar di sini

Yodagama
sumber
24

Saya akhirnya menemukan ini, saya harap ini lebih mudah dimengerti.

Anda sering dapat melewati peringatan itu dengan menambahkan UIView baru ke scrollview sebagai "tampilan konten", seperti yang mereka sebutkan dan menjadikannya ukuran yang sama dengan tampilan gulir Anda dan, pada tampilan konten ini, atur 6 parameter ini.

masukkan deskripsi gambar di sini

Seperti yang Anda lihat, Anda membutuhkan 6 parameter total! Yang .. dalam keadaan normal, Anda menduplikasi 2 kendala tetapi ini adalah cara untuk menghindari kesalahan storyboard ini.

William T.
sumber
1
Di atas hampir berhasil bagi saya, karena saya khawatir tentang 3 lebar layar yang berbeda (4/5, 6, 6+) Saya mengatur tampilan konten dan menggulir tampilan untuk memiliki lebar yang sama. Anda benar, ini merupakan duplikat karena saya telah mengatakan pada tampilan konten untuk memiliki 0 ruang awal dan akhir.
Stuart P.
8
Anda dapat mengatur batasan lebar dan tinggi yang sama dari tampilan konten ke tampilan gulir, alih-alih nilai konstan. Ini akan bekerja pada semua resolusi.
Kumar C
Saya harus menerapkan yang sama, jadi bisakah Anda membantu saya bahwa saya harus mengatur tinggi dan lebar yang sama untuk tampilan konten dan tampilan gulir?
Urmi
Mungkin perlu diperiksa untuk melihat apakah Anda masih harus melakukan ini. Saya mengatur imageView di scrollview baru-baru ini dan bisa pergi dengan hanya menetapkan 4 kendala yang ditunjukkan di atas untuk membuat kesalahan hilang di Xcode 8.3
William T.
1
@Honey ini diposting lebih dari 3 tahun yang lalu. Mereka pasti meningkatkan storyboard sejak itu. Saya juga perhatikan Anda dapat pergi tanpa tampilan konten sekarang. Saya akan menyesuaikan jawaban saya.
William T.
16

Saya tahu saya mungkin terlambat, tetapi solusi berikutnya memecahkan masalah semacam ini tanpa kode tambahan , hanya menggunakan storyboard:

Untuk tampilan konten Anda, Anda perlu menetapkan batasan untuk memimpin / mengikuti / spasi atas / bawah ke scrollview dan ini tidak akan mengubah bingkai tampilan konten , seperti ini:masukkan deskripsi gambar di sini

Tentu saja Anda perlu membuat batasan tambahan untuk tampilan konten sehingga tampilan gulir bisa mengetahui ukuran konten. Misalnya mengatur tinggi dan pusat tetap x.

Semoga ini membantu.

Borzh
sumber
7

Bagi saya menambahkan contentViewtidak benar-benar berfungsi seperti yang disarankan. Selain itu, ini menciptakan overhead karena tampilan yang ditambahkan (walaupun saya tidak menganggap ini masalah besar). Apa yang paling berhasil bagi saya adalah mematikan ambiguitas-memeriksa saya scrollView. Semuanya meletakkan dengan baik jadi saya pikir tidak apa-apa dalam kasus-kasus sederhana seperti milik saya. Namun perlu diingat, bahwa jika kendala lain untuk scrollViewistirahat Anda , Interface-Builder tidak akan memperingatkan Anda lagi tentang hal itu.

masukkan deskripsi gambar di sini

Nick Podratz
sumber
5
Ini hanya akan menghapus peringatan dan tidak melakukan apa pun untuk menyelesaikan masalah.
Predrag Manojlovic
Kamu. adalah. saya. pahlawan. Tidak menyadari ini ada dan senang menemukannya! Saya mencoba "Verifikasi Posisi Saja" yang Anda harapkan, saya tidak tahu, memverifikasi posisi saja tetapi tidak ada yang memungkinkan masalah "ukuran konten" yang bermasalah ini. Harus pergi dengan "Never Verify". Terima kasih!
Dustin
Saya pikir ini adalah jawaban yang tepat jika Anda membuat tampilan anak secara terprogram. Terima kasih!
Florian Kusche
6

Lihat ini sangat cepat dan langsung ke tutorial tentang cara membuat tampilan gulir bekerja dan sepenuhnya dapat digulir dengan tata letak otomatis. Sekarang, satu-satunya hal yang masih membuat saya bingung adalah mengapa ukuran konten tampilan gulir selalu lebih besar dari yang diperlukan ..

http://samwize.com/2014/03/14/how-to-use-uiscrollview-with-autolayout/

Mike Simz
sumber
3

Lihat di bawah: tampilan konten dalam scrollview vertikal dan horizontal terpusat. Anda mendapat kesalahan ambiguitas, selalu pastikan dua ditambahkan ke scrollview dari tampilan konten Anda adalah 1) .tombol spasi ke penampung.2) mengekor spasi ke batasan yang disorot dalam tangkapan layar,

kendala ini berarti dalam gulir adalah seberapa banyak Anda dapat menggulir setelah konten Anda melihat tinggi atau lebar.

masukkan deskripsi gambar di sini

mungkin membantu Anda.

Ravi Kumar
sumber
3

Saya memecahkan masalah semacam ini untuk pandangan saya dengan menggunakan "Selesaikan masalah tata letak otomatis"> "Tambahkan kendala yang hilang" untuk Tampilan Terpilih masukkan deskripsi gambar di sini

Dua kendala berikut memecahkan masalah saya:

trailing = Stack View.trailing - 10
bottom = Stack View.bottom + 76

di mana: trailing, bottom adalah trailing, bottom dari UIScrollView

Linh Dao
sumber
Ini berhasil bagi saya dengan menambahkan batasan "ke bawah". Sekarang saya memikirkannya, itu masuk akal.
SilverWolf - Kembalikan Monica
3

Menggunakan contentView ( UView) sebagai wadah dalam UIScrollView, tongkat ke tepi ( top, bottom, trailing, leading) dari SuperView ( UIScrollView) dan contentViewharus memiliki equalwidthdan equalheightuntuk SuperView. Itu adalah kendala. Dan panggilan metode:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.scrollView.contentSize = self.contentView.frame.size;
}

Memecahkan masalah bagi saya.

Spiridon Kopicl
sumber
3

Pendekatan Swift 4+:

1) Setel UIScrollView margin atas, bawah, kiri dan kanan ke 0

2) Di dalam UIScrollView tambahkan UIView dan atur margin atas, bawah, depan, akhir menjadi 0 (sama dengan margin UIScrollView).

3) Bagian terpenting adalah mengatur lebar dan tinggi, di mana batasan ketinggian harus memiliki prioritas rendah .

private func setupConstraints() {

    // Constraints for scrollView
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    // Constraints for containerView
    containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
    containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

    let heightConstraint = containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
    heightConstraint.priority = UILayoutPriority(rawValue: 250)
    heightConstraint.isActive = true
}
Gentian Sadiku
sumber
2

@Matteo Gobbi jawaban sempurna, tetapi dalam kasus saya, scrollview tidak dapat menggulir, saya menghapus " align center Y " dan tambahkan " height> = 1 ", scrollview akan menjadi scrollable

ygweric
sumber
2

Orang-orang yang berjuang dengan uiscrollview tidak menggulir cukup menetapkan batasan bawah tampilan konten Anda dengan tata letak bawah tampilan terakhir Anda (yang ada di dalam tampilan konten Anda). Jangan lupa untuk menghapus batasan pusat Y.

Istirahat semua kendala sama seperti yang didefinisikan di atas. Scrollview hanya peduli tentang mendapatkan ketinggian maksimum dari tampilan kontennya, dan kami menetapkannya sebagai kendala bawah tampilan terakhir, yang berarti scrollview secara otomatis akan mengubah offset kontennya.

Dalam kasus saya, tampilan terakhir adalah UILable tanpa garis properti = 0 (yang secara otomatis menyesuaikan ketinggiannya tergantung pada isinya) sehingga secara dinamis meningkatkan ketinggian uilable dan akhirnya area yang dapat digulir bertambah karena tata letak bawah uilable disejajarkan dengan bagian bawah tampilan konten kami, yang memaksa scrollview untuk meningkatkan konten diimbangi.

Siddhesh Mahadeshwar
sumber
2

Saya membuat video di youTube
Scroll StackViews hanya menggunakan Storyboard di Xcode

Saya pikir 2 jenis skenario bisa muncul di sini.

Tampilan di dalam scrollView -

  1. tidak memiliki Ukuran konten intrinsik (mis. UIView)
  2. memang memiliki Ukuran konten intrinsik sendiri (misalnya UIStackView)

Untuk tampilan yang dapat digulirkan secara vertikal dalam kedua kasus, Anda perlu menambahkan batasan ini:

  1. 4 kendala dari atas, kiri, bawah dan kanan.

  2. Lebar sama dengan scrollview (untuk berhenti menggulir secara horizontal)

Anda tidak memerlukan kendala lain untuk tampilan yang memiliki tinggi konten intrinsiknya sendiri.

masukkan deskripsi gambar di sini


Untuk tampilan yang tidak memiliki tinggi konten intrinsik, Anda perlu menambahkan batasan ketinggian. Tampilan akan bergulir hanya jika batasan ketinggian lebih dari ketinggian scrollView.

masukkan deskripsi gambar di sini

Warif Akhand Rishi
sumber
2
import UIKit

class ViewController: UIViewController {

    //
    let scrollView: UIScrollView = {

        let sv = UIScrollView()
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()

    let lipsumLbl: UILabel = { // you can use here any of your subview

        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.text = """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce eleifend nisi sit amet mi aliquet, ut efficitur risus pellentesque. Phasellus nulla justo, scelerisque ut libero id, aliquet ullamcorper lectus. Integer id iaculis nibh. Duis feugiat mi vitae magna tincidunt, vitae consequat dui tempor. Donec blandit urna nec urna volutpat, sit amet sagittis massa fringilla. Pellentesque luctus erat nec dui luctus, sed maximus urna fermentum. Nullam purus nibh, cursus vel ex nec, pulvinar lobortis leo. Proin ac libero rhoncus, bibendum lorem sed, congue sapien. Donec commodo, est non mollis malesuada, nisi massa tempus ipsum, a varius quam lorem vitae nunc.

        Cras scelerisque nisi dolor, in gravida ex ornare a. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas vitae nisl id erat sollicitudin accumsan sit amet viverra sapien. Etiam scelerisque vulputate ante. Donec magna nibh, pharetra sed pretium ac, feugiat sit amet mi. Vestibulum in ipsum vitae dui vehicula pulvinar eget ut lectus. Fusce sagittis a elit ac elementum. Fusce iaculis nunc odio, at fermentum dolor varius et. Suspendisse consectetur congue massa non gravida. Sed id elit vitae nulla aliquam euismod. Pellentesque accumsan risus dolor, eu cursus nibh semper id.

        Vestibulum vel tortor tellus. Suspendisse potenti. Pellentesque id sapien eu augue placerat dictum. Fusce tempus ligula at diam lacinia congue in ut metus. Maecenas volutpat tellus in tellus maximus imperdiet. Integer dignissim condimentum lorem, id luctus nisi maximus at. Nulla pretium, est sit amet mollis eleifend, tellus nulla viverra dolor, ac feugiat massa risus a lectus. Pellentesque ut pulvinar urna, blandit gravida ipsum. Nullam volutpat arcu nec fringilla auctor. Integer egestas enim commodo, faucibus neque ac, rutrum magna. Vivamus tincidunt rutrum auctor. Cras at rutrum felis. Fusce elementum lorem ut pharetra venenatis.
        """
        lbl.textColor = .darkGray
        lbl.font = UIFont.systemFont(ofSize: 16)
        lbl.numberOfLines = 0
        return lbl
    }()

    //======================================================================//
    //
    // MARK:- viewDidLoad
    //
    override func viewDidLoad() {
        super.viewDidLoad()

        setupViews()
        setupAutoLayout()
    }

    func setupViews() {

        title = "ScrollView Demo"
        view.backgroundColor = .white
        view.addSubview(scrollView)
        scrollView.addSubview(lipsumLbl)
    }

    func setupAutoLayout() {

        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        lipsumLbl.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        lipsumLbl.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        lipsumLbl.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        lipsumLbl.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        lipsumLbl.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    }
}

Keluaran:

masukkan deskripsi gambar di sini

iAj
sumber
mengapa Anda perlu memimpinAnchor ketika Anda sudah meninggalkanAnchor?
ShadeToD
leftAnchor tidak dapat digunakan untuk tujuan ini, jadi kami harus menggunakan leadingAnchor untuk mencapai yang sama ..
iAj
Anda menggunakan keduanya dalam contoh Anda.
ShadeToD
@ShadeToD izinkan saya memeriksa
iAj
2

Dalam kasus saya, saya menerima masalah ukuran konten dan Ambiguitas Ukuran konten yang salah di iPad tetapi berfungsi untuk iPhone. Saya telah melakukan perubahan berikut di storyboard untuk menyelesaikan masalah ini.

  1. Tambahkan scrollview di UIView dan tambahkan kendala leading, top, trailing dan bottom menjadi 0,0,0,0.
  2. Tetapkan ketinggian tampilan gulir sesuai persyaratan untuk mis. 100.
  3. Tambahkan UIView untuk menggulir tampilan dan menambahkan kendala memimpin, atas, membuntuti dan bawah ke 0,0,0,0 dan menyelaraskan kendala pusat (X) dan pusat (Y).
  4. Hapus centang "Pedoman Tata Letak Konten" di inspektur ukuran tampilan gulir.
Daljeet Seera
sumber
1

Pengguliran Vertikal

  1. Tambahkan UIScrollView dengan kendala 0,0,0,0 ke superview.
  2. Tambahkan UIView di ScrollView, dengan kendala 0,0,0,0 untuk superview.
  3. Tambahkan batasan lebar yang sama untuk UIView ke UIScrollView.
  4. Tambahkan Tinggi ke UIView.
  5. Tambahkan elemen dengan kendala ke UIView.
  6. Untuk elemen yang paling dekat dengan bagian bawah, pastikan ia memiliki batasan untuk bagian bawah UIView.
Bitcon
sumber
0

Apa yang saya lakukan adalah membuat tampilan konten terpisah seperti yang ditunjukkan di sini.

Tampilan konten adalah bentuk bebas dan dapat memiliki semua subview ditambahkan dengan kendala mereka sendiri sehubungan dengan contentView.

UIScrollView ditambahkan ke pengontrol tampilan utama.

Secara pemrograman saya menambahkan contentView yang terhubung melalui IBOutlet ke kelas dan mengatur contentView dari UIScrollView.

UIScrollView dengan ContentView melalui Interface Builder

Vlad
sumber
0

Saya mendapatkan kesalahan yang sama .. saya telah melakukan yang berikut

  1. Lihat (Superview)
  2. ScrollView 0,0,600,600
  3. UIView di dalam ScrollView: 0,0,600,600
  4. UIView berisi tampilan gambar, label

Sekarang tambahkan leading / trailing / top / bottom untuk scrollView (2) kemudian UIView (3).

Pilih Lihat (1) dan Lihat (3) mengatur tinggi dan berat yang sama .. itu memecahkan masalah saya.

Saya telah melakukan video yang akan membantu:

https://www.youtube.com/watch?v=s-CPN3xZS1A

Vinod Joshi
sumber
0

[diuji dalam XCode 7.2 dan untuk iOS 9.2]

Apa yang menekan kesalahan dan peringatan Storyboard bagi saya adalah menetapkan ukuran intrinsik dari tampilan gulir dan tampilan konten (dalam kasus saya, sebuah stackview) ke Placeholder . Pengaturan ini ditemukan di inspektur Ukuran di Storyboard. Dan katanya - Mengatur waktu desain ukuran konten intrinsik hanya memengaruhi tampilan saat mengedit di Interface Builder. Tampilan tidak akan memiliki ukuran konten intrinsik ini saat runtime.

Jadi, saya kira kita tidak salah dengan mengatur ini.

Catatan: Di storyboard, saya telah menyematkan semua tepi scrollview ke superview dan semua tepi stackview ke scrollview. Dalam kode saya, saya telah menetapkan translatesAutoresizingMaskIntoConstraints sebagai false untuk scrollview dan stackview. Dan saya belum menyebutkan ukuran konten. Ketika stackview tumbuh secara dinamis, kendala yang diatur dalam storyboard memastikan bahwa stack dapat digulir.

Peringatan storyboard membuatku gila dan aku tidak ingin memusatkan hal-hal secara horizontal atau vertikal hanya untuk menekan peringatan.

gtl_pm
sumber
0

Jika ada yang mendapatkan perilaku di mana Anda melihat bilah gulir di gulungan kanan tetapi kontennya tidak bergerak, fakta ini mungkin layak dipertimbangkan:

Anda juga dapat menggunakan batasan antara konten tampilan gulir dan objek di luar tampilan gulir untuk memberikan posisi tetap untuk konten tampilan gulir, membuat konten itu tampak melayang di atas tampilan gulir.

Itu dari dokumentasi Apple . Misalnya, jika Anda secara tidak sengaja menyematkan Label / Tombol / Img / Tampilan atas ke tampilan di luar area gulir (Mungkin tajuk atau sesuatu di atas scrollView?) Alih-alih contentView, Anda akan membekukan seluruh konten Anda di tempatnya.

Dave G
sumber
0

Seperti disebutkan dalam jawaban sebelumnya, Anda harus menambahkan tampilan khusus di dalam tampilan gulir:

Tampilan khusus adalah ContentView yang ditandai dalam gambar

Tambahkan semua subview Anda ke tampilan konten. Pada titik tertentu Anda akan melihat tampilan konten gulir memiliki peringatan ukuran konten yang ambigu, Anda harus memilih tampilan konten dan klik tombol "Selesaikan masalah tata letak otomatis" (di sudut kanan bawah tata letak IB), dan pilih "Tambah yang hilang opsi kendala ".

masukkan deskripsi gambar di sini

Mulai sekarang ketika Anda menjalankan proyek, tampilan gulir akan secara otomatis memperbarui ukuran kontennya, tidak diperlukan kode tambahan.

supergeg
sumber
0

Anda hanya perlu memastikan bahwa ada cara untuk membuat garis kendala terus menerus dari atas ke bawah scrollview. [-XXX]

Dalam kasus saya - tampilan gulir yang bergulir secara horizontal - Saya juga perlu menambahkan batasan lebar dan tinggi untuk setiap anak dari tampilan gulir, meskipun catatan teknis Apple tidak memberi tahu Anda hal ini.

johnnyMac
sumber
0

Jika Anda masih memiliki masalah dengan UIScrollView, matikan saja Panduan Tata Letak Konten (Pilih ScrollView Anda di xcode Interface Builder -> pilih Size inspector di panel kanan -> batalkan pilihan 'Content Layout Guides') Atau coba langkah-langkah ini: xcode 11 layout tampilan gulir - ini dapat berguna untuk gaya tata letak baru. Bekerja dengan baik di macOS 10.15.2, Xcode 11.3.1, untuk 05.02.2020

lihat tangkapan layar

Victor Doshenko
sumber
0

Menggunakan Autolayout

Tambahkan tampilan gulir Anda di dalam tampilan yang ditentukan dengan baik dan kemudian tambahkan tampilan tumpukan di dalam tampilan gulir

Tambahkan batasan atas, kiri, kanan, bawah, tengah X dan tengah Y dari tampilan gulir dan tampilan tumpukan ke tampilan super yang relevan

Pastikan kendala ditautkan dari tampilan tumpukan ke superview yang sah (scrollview) karena pengaturan default saat ini adalah menambahkan kendala Align Top dan bukan Space Top.

Ahmed Elashker
sumber