UIScrollView tidak menggulir

128

Saya memiliki UIScrollViewyang berisi banyak UIImageViews, label UIL, dll ... label jauh lebih lama daripada itu UIScrollView, tetapi ketika saya menjalankan aplikasi, saya tidak bisa mengklik dan gulir ke bawah ...

Mengapa ini bisa terjadi?

Terima kasih

Menandai
sumber
Baru 3/26/2013 Saya menemukan cara yang lebih mudah untuk melakukan ini tanpa kode (mengatur contentSize) stackoverflow.com/a/15649607/1705353
Dickey Singh

Jawaban:

169

Itu selalu baik untuk menunjukkan potongan kode kerja lengkap:

// in viewDidLoad (if using Autolayout check note below):

UIScrollView *myScrollView;
UIView *contentView;
// scrollview won't scroll unless content size explicitly set

[myScrollView addSubview:contentView];//if the contentView is not already inside your scrollview in your xib/StoryBoard doc

myScrollView.contentSize = contentView.frame.size; //sets ScrollView content size

Cepat 4.0

let myScrollView
let contentView

// scrollview won't scroll unless content size explicitly set

myScrollView.addSubview(contentView)//if the contentView is not already inside your scrollview in your xib/StoryBoard doc

myScrollView.contentSize = contentView.frame.size //sets ScrollView content size

Saya belum menemukan cara untuk mengatur contentSize di IB (pada Xcode 5.0) .

Catatan: Jika Anda menggunakan Autolayout, tempat terbaik untuk meletakkan kode ini ada di dalam -(void)viewDidLayoutSubviewsmetode.

Bogatyr
sumber
12
Jangan lupa untuk mengatur myScrollView.delegate = selfJUGA, jika ini masih tidak berfungsi, jawaban di bawah ini memiliki saran HEBAT (buka xib / StoryBoard Anda dan pastikan "AutoLayout" dinonaktifkan). Pro-Tip: Anda juga dapat memasukkan <UIScrollViewDelegate>dalam file .h Anda jika Anda ingin melakukan hal-hal seperti gulir secara terprogram UIScrollView Anda.
Albert Renshaw
1
@AlbertRenshaw Anda seharusnya menambahkan jawaban sehingga saya bisa memberi Anda +1 :) AutoLayout adalah masalah dengan saya .... membuat saya gila selama 4 jam.
logixologist
2
Memasukkan kode viewDidLayoutSubviewsmembuatnya bekerja untuk saya.
Amr Lotfy
Bagi saya masalahnya adalah tidak perlu menggulir, karena semuanya sesuai di layar.
Daniel Springer
122

Jika Anda tidak dapat menggulir tampilan bahkan setelah Anda mengatur contentSize dengan benar, pastikan Anda hapus centang "Gunakan AutoLayout" di Interface Builder -> File Inspector.

pengguna1539652
sumber
164
Atau, Anda dapat mengatur contentSize di viewDidLayoutSubviews :, dan itu akan diterapkan setelah autolayout selesai.
Chris Vasselli
2
@ "Chris Vasselli" slove masalah saya .. GR8 .. :-)
Ayaz
3
Komentar Chris harus menjadi jawaban yang terpisah!
ninjaneer
1
Terima kasih banyak, Chris Vasselli! Dengan Auto Layout diaktifkan, itu tidak akan berfungsi di viewDidLoad tetapi tidak dengan viewDidLayoutSubviews!
Romain
1
Woah, saya tidak pernah memperhatikan semua komentar ini sebelumnya! Senang saya bisa membantu banyak dari Anda! Saya baru saja memposting jawaban terpisah sehingga mudah-mudahan akan lebih mudah ditemukan.
Chris Vasselli
68

Anda perlu mengatur contentSize properti tampilan gulir agar dapat menggulir dengan benar.

Jika Anda menggunakan AutoLayout, Anda perlu set contentSizedi viewDidLayoutSubviewsdalam rangka untuk itu harus diterapkan setelah selesai AutoLayout.

Kode dapat terlihat seperti ini:

-(void)viewDidLayoutSubviews
{
    // The scrollview needs to know the content size for it to work correctly
    self.scrollView.contentSize = CGSizeMake(
        self.scrollContent.frame.size.width,
        self.scrollContent.frame.size.height + 300
    );
}
Chris Vasselli
sumber
Terima kasih banyak .. Ini berhasil karena beberapa alasan, bahkan ketika saya menetapkan nilai contentSizeuntuk ukuran contentView, ukuran scrollView dan contentView tampaknya diset sebagai sama. Tetapi pengaturan tinggi contentSizenilai lebih tinggi dari tinggi contentView, itu berhasil.
Skywalker
viewDidLayoutSubviewsdapat dipanggil beberapa kali selama siklus hidup sehingga Anda berisiko meningkatkan ketinggian lebih besar dari yang diharapkan.
anon_nerd
@anon_nerd hanya memeriksa apakah sudah dipanggil dan hanya menambah tinggi jika tidak
Daniel Springer
45

Jawaban di atas benar - untuk membuat scrolling terjadi, perlu untuk mengatur ukuran konten.

Jika Anda menggunakan pembuat antarmuka cara yang rapi untuk melakukannya adalah dengan atribut runtime yang ditentukan pengguna. Misalnya:

masukkan deskripsi gambar di sini

Jasper Blues
sumber
ini tidak melakukan apa pun untuk saya.
coolcool1994
4
Ups, gambarnya menunjukkan {0, 0}, tetapi Anda tentu harus memasukkan angka yang cukup besar. . pendekatan ini hanya akan berfungsi untuk tampilan sederhana di mana Anda tahu ukuran konten di muka. . . (pada kenyataannya, untuk tampilan kompleks, saya merekomendasikan kode murni).
Jasper Blues
Jauh lebih sedikit meretas daripada melakukannya secara terprogram. Terima kasih!
Jake Stoeffler
1
@JakeStoeffler selamat datang! :) Saat menggunakan IB, saya suka menyimpan semua konfigurasi di sana (tidak terfragmentasi). Tetapi ketika hal-hal menjadi kompleks (widget tampilan dapat digunakan kembali; model adapter, manipulasi layer; CAAnimations, dll) maka saya lebih suka pandangan sepenuhnya terprogram. . . lebih lancar.
Jasper Blues
Saya mencoba ini, berfungsi ketika tampilan muncul, tetapi pada perubahan orientasi, contentSize yang ditentukan pada layar di atas diabaikan dan log saya mengatakan contentSize diatur kembali 0,0. Adakah cara untuk memperbaikinya?
Shoogle
40

Cobalah untuk mengubah ukuran ukuran konten menjadi angka besar. Saya tidak mengerti mengapa tampilan gulir saya tidak menggulir bahkan ketika ukuran kontennya tampaknya lebih besar dari ukuran kontrol. Saya menemukan bahwa jika ukuran konten lebih kecil dari yang dibutuhkan, itu tidak berfungsi juga.

self.scrollView.contentSize = CGSizeMake(2000, 2000);

Alih-alih tahun 2000 Anda bisa memasukkan angka besar Anda sendiri. Dan jika berhasil, itu berarti bahwa ukuran konten Anda tidak cukup besar ketika Anda mengubah ukuran.

Delegasi tidak diperlukan agar tampilan gulir berfungsi.

Denis Kutlubaev
sumber
2
Genius - cara sederhana untuk memeriksa apa yang sedang terjadi. Terima kasih banyak!
The Crazy Chimp
13

Pastikan Anda memiliki properti contentSize dari tampilan gulir diatur ke ukuran yang benar (yaitu, satu yang cukup besar untuk mencakup semua konten Anda.)

Ben Gottlieb
sumber
1
apakah saya harus melakukan ini secara terprogram? atau bisakah saya melakukannya di IB?
Tandai
Jika Anda menggunakan IB, Anda dapat mengaturnya dari sana - lihat di bawah. . (Pisahkan jawaban, jadi saya bisa memasukkan foto).
Jasper Blues
7

Hapus centang 'Gunakan Autolayout' lakukan trik untuk saya.

Lingkungan: xCode 5.0.2 Storyboards ios7

Gaurav Kumkar
sumber
5

Dalam kasus saya, saya harus mengatur delaysContentToucheske true karena objek di dalam scrollView semuanya menangkap peristiwa sentuh dan menangani sendiri daripada membiarkan scrollView sendiri yang menanganinya.

devios1
sumber
Saya memiliki masalah yang sama. Masalahnya bagi saya adalah dengan mengubah delaysContentTouches menjadi true, Anda akan berakhir dengan gambar berkualitas lebih rendah dengan pensil apel. Tapi ini adalah kasus tepi :) dalam banyak kasus itu memecahkan masalah
RomOne
4

Setel contentSizeproperti UIScrollviewdalam ViewDidLayoutSubviewsmetode. Sesuatu seperti ini

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}
Vinayak Parmar
sumber
3

Gagasan mengapa tampilan gulir tidak menggulir karena Anda mengatur ukuran konten untuk menggulir kurang dari ukuran tampilan gulir, yang salah. Anda harus mengatur ukuran konten lebih besar dari ukuran tampilan gulir Anda untuk menavigasi saat menggulir.

Ide yang sama dengan zooming, Anda mengatur nilai min dan max untuk zooming yang akan diterapkan melalui aksi zooming.

Selamat datang :)

Abo3atef
sumber
3

Satu tambahan kecil, semua di atas adalah alasan sebenarnya mengapa tampilan gulir Anda mungkin tidak menggulir tetapi kadang-kadang tanpa alasan ini bisa menjadi alasan khusus ketika scrollview ditambahkan melalui kode dan bukan IB, Anda mungkin telah menambahkan subview Anda ke tampilan induk dan tidak untuk scrollview ini menyebabkan subview tidak bergulir

dan tetap atur ukuran konten dan lebih besar dari bingkai tampilan orang tua (duhh !!)

Abhinav Singh
sumber
3

Saya membuatnya bekerja pada percobaan pertama saya. Dengan tata letak otomatis dan segalanya, tidak ada kode tambahan. Kemudian tampilan koleksi menjadi pisang, terhempas pada waktu berjalan, saya tidak dapat menemukan apa yang salah, jadi saya menghapus dan membuatnya kembali (saya menggunakan Xcode 10 Beta 4. Rasanya seperti bug) dan kemudian penggulirannya hilang. Tampilan Koleksi bekerja lagi!

Beberapa jam kemudian .. inilah yang diperbaiki untuk saya. Saya memiliki tata letak berikut:

UIView

  • Area aman
  • Tampilan gulir
    • Tampilan konten

Semuanya ada dalam kendala. Area Aman secara otomatis ditentukan oleh sistem. Dalam kasus terburuk, hapus semua kendala untuk tampilan gulir dan konten dan tidak ada IB yang mengatur ulang / membuatnya untuk Anda. Buat mereka secara manual, ini berfungsi.

  • Untuk Scroll view yang saya lakukan: Align Trailing / Top to Safe Area. Lebar / Tinggi yang Sama dengan Area Aman .
  • Untuk tampilan Konten yang saya lakukan: Align Trailing / Leading / Top / Bottom to Superview (tampilan gulir)

pada dasarnya konsepnya adalah untuk memiliki Content view fitting Scrollview, yang sesuai dengan Safe Area.

Tetapi karena itu tidak berhasil. Tampilan konten merindukan ketinggian. Saya mencoba semua yang saya bisa dan satu-satunya yang melakukan trik adalah Ketinggian tampilan Konten yang menciptakan tampilan Konten yang menyeret kontrol .. untuk dirinya sendiri . Yang menentukan ketinggian tetap, yang nilainya telah dihitung dari Ukuran pengontrol tampilan (didefinisikan sebagai bentuk bebas, lebih panjang dari tampilan sebenarnya, hingga berisi semua subview saya) dan akhirnya berhasil lagi!

Michele Dall'Agata
sumber
Sama-sama! Saya tahu persis bagaimana perasaan Anda .. ;-)
Michele Dall'Agata
Terima kasih, saya menghabiskan banyak waktu dan ini memecahkan masalah saya
Andoni Da Silva
3

jika Anda menerima pesan (iOS8 / swift) yang viewDidLayoutSubviewstidak ada, gunakan yang berikut ini sebagai gantinya

override func viewDidAppear(animated: Bool)

Ini memperbaikinya untuk saya

Jason G
sumber
2

Sesuatu yang tidak disebutkan sebelumnya!

Pastikan outlet Anda terhubung dengan benar ke scrollView! Seharusnya lingkaran diisi, tetapi meskipun Anda telah mengisi lingkaran, scrollView mungkin tidak terhubung - jadi periksa dua kali! Arahkan kursor ke atas lingkaran dan lihat apakah scrollview aktual disorot! (Ini adalah kasus bagi saya)

//Connect below well to the scrollView in the storyBoard
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
coolcool1994
sumber
2

Banyak waktu kode benar jika Anda telah mengikuti tutorial tetapi apa yang banyak pemula tidak tahu adalah bahwa scrollView TIDAK akan menggulir secara normal melalui simulator. Seharusnya untuk menggulir hanya ketika Anda menekan mousepad dan secara bersamaan gulir. Banyak pengguna XCode / Swift / Obj-C yang berpengalaman sangat terbiasa melakukan hal ini dan mereka tidak tahu bagaimana hal itu dapat diabaikan oleh pemula. Ciao :-)

@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(scrollView)
    // Do any additional setup after the view
}

override func viewWillLayoutSubviews(){
    super.viewWillLayoutSubviews()
    scrollView.contentSize = CGSize(width: 375, height: 800)
}

Kode ini akan berfungsi dengan baik selama Anda melakukan apa yang saya katakan di atas

flo527
sumber
1

Jika tidak ada solusi lain yang berfungsi untuk Anda, periksa kembali apakah tampilan gulir Anda sebenarnya adalah a UIScrollView di Interface Builder.

Pada beberapa titik dalam beberapa hari terakhir, UIScrollView tipe spontan saya berubah menjadi a UIView, meskipun kelasnya mengatakan UIScrollViewdi inspektur. Saya menggunakan Xcode 5.1 (5B130a).

Anda dapat membuat tampilan gulir baru dan menyalin pengukuran, pengaturan, dan batasan dari tampilan lama, atau Anda dapat secara manual mengubah tampilan Anda ke UIScrollViewdalam xibfile. Saya melakukan perbandingan dan menemukan perbedaan berikut:

Asli:

<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wsk-WB-LMH">
...
</scrollView>

Setelah jenis berubah secara spontan:

<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIScrollView" id="qRn-TP-cXd">
...
</view>

Jadi saya mengganti <view>garis dengan <scrollView>garis asli saya .

Saya juga mengganti tag penutup tampilan </view>dengan </scrollView>.

Pastikan id tetap sama dengan tampilan saat ini, dalam hal ini: id = "qRn-TP-cXd".

Saya juga harus menyiram xib dari cache Xcode dengan menghapus data turunan aplikasi:

  • Xcode->Window->Organizer->Projects, pilih proyek Anda, pada baris Data Turunan, klik Hapus ...

Atau jika menggunakan perangkat:

  • Xcode->Window->Organizer->Device, pilih perangkat Anda-> Aplikasi, pilih aplikasi Anda, klik (-)

Sekarang bersihkan proyek, dan hapus aplikasi dari simulator / perangkat:

  • Xcode->Product->Clean
  • iOS Simulator/device->pressdan tahan app->clicktombol (X) untuk menghapusnya

Anda kemudian dapat membangun dan menjalankan aplikasi Anda dan memiliki fungsi gulir lagi.

PS Saya tidak perlu mengatur ukuran konten tampilan gulir viewDidLayoutSubviewsatau mematikan tata letak otomatis, tetapi YMMV.

Zack Morris
sumber
1

Jika Anda scrollViewadalah subview dari containerViewjenis tertentu, maka pastikan bahwa Anda scrollViewberada dalam bingkai atau batas dari containerView. Saya memiliki containerView.clipsToBounds = NOyang masih memungkinkan saya melihat scrollView, tetapi karena scrollViewtidak dalam batas containerViewitu tidak akan mendeteksi acara sentuh.

Sebagai contoh:

containerView.frame = CGRectMake(0, 0, 200, 200);
scrollView.frame = CGRectMake(0, 200, 200, 200);
[containerView addSubview:scrollView];
scrollView.userInteractionEnabled = YES;

Anda akan dapat melihat scrollView tetapi tidak akan menerima interaksi pengguna.

Chase Roberts
sumber
1

menambahkan kode berikut ini viewDidLayoutSubviewsberfungsi untuk saya dengan Autolayout. Setelah mencoba semua jawaban:

- (void)viewDidLayoutSubviews
{
    self.activationScrollView.contentSize = CGSizeMake(IPHONE_SCREEN_WIDTH, 620);

}

//set the height of content size as required
IPhone yang cerdas
sumber
1

Tambahkan UIScrollViewDelegatedan tambahkan kode berikut ke viewDidAppearmetode yang diperbaiki untuk saya.

@interface testScrollViewController () <UIScrollViewDelegate>

-(void)viewDidAppear:(BOOL)animated {
    self.scrollView.delegate = self;
    self.scrollView.scrollEnabled = YES;
    self.scrollView.contentSize = CGSizeMake(375, 800);
}
Trianna Brannon
sumber
1

Masalah saya diselesaikan oleh:

  1. mengatur contentSize pada scrollView ke ketinggian besar
  2. TETAPI saya juga harus memperbaiki batasan atas dan / atau bawah pada tampilan dalam scrollView, yang berarti indikator gulir ditampilkan di layar tetapi konten tidak menggulir.

Setelah saya menghapus batasan atas dan / atau bawah yang terikat pada area aman dan / atau superview, tampilan di dalam scrollView dapat menggulir lagi dan tidak tetap terpaku pada bagian atas layar!

Semoga ini menghentikan orang lain dari berjam-jam kesakitan dengan masalah khusus ini.

Henry Heleine
sumber
1

kasus menyenangkan lainnya:

scrollview.superview.userInteractionEnabled harus benar

Saya menyia-nyiakan 2 + jam mengejar ini hanya untuk mengetahui induknya adalah UIImageView yang, secara alami, memiliki userInteractionEnabled == false

Anton Tropashko
sumber
0

Setelah gagal dengan jawaban yang disediakan di utas ini, saya menemukan artikel ini dengan solusinya.

Ada dua hal yang tidak intuitif tentang pengaturan scrollview dengan autolayout:

  1. Kendala yang Anda atur sebagai margin antara tampilan konten dan tampilan scroll tidak mempengaruhi ukuran tampilan konten. Mereka benar-benar margin. Dan untuk membuatnya bekerja, tampilan konten harus memiliki ukuran yang tetap.
  2. Trik untuk ukuran tetap adalah bahwa Anda dapat mengatur lebar tampilan konten sama dengan orang tua scrollview itu. Cukup pilih kedua tampilan di pohon di sebelah kiri dan tambahkan batasan lebar yang sama.

Ini adalah inti dari artikel itu. Untuk penjelasan lengkap, termasuk ilustrasi, lihatlah.

H. de Jonge
sumber
@PredragManojlovic Bagaimana bisa lebih umum dari ini? Ini adalah satu-satunya cara saya bisa mendapatkan scrollview agar berfungsi dengan baik, menggunakan tata letak otomatis.
H. de Jonge
0

Saya menemukan bahwa dengan masalah AutoLayout ini ... jika saya hanya ViewControllermenggunakan UIViewbukan UIScrollViewuntuk kelas ... maka tambahkan saja UIScrollViewsendiri ... bahwa itu berfungsi.

Brian Rice
sumber
0

Saya memiliki masalah yang sama di IB.

Setelah mengatur leading, trailing, atas dan bawah scrollView ke superView. Saya membuat perubahan berikut untuk membuat containerView dapat digulir, yang berfungsi.

Untuk membuat scrollView hanya gulir pada arah horizontal, buat batasan dengan scrollView centerY = ContainerView's centerY

dan untuk membuatnya dapat digulirkan secara vertikal, buat scrollView's centerX = ContainerView's centerX

Nandu
sumber