Bagaimana cara menonaktifkan pengguliran horizontal UIScrollView?

92

Saya memiliki UIViewSpringboard seperti iPhone. Saya telah membuatnya menggunakan UIScrollViewdan UIButtons. Saya ingin menonaktifkan pengguliran horizontal pada scrollview tersebut. Saya hanya ingin pengguliran vertikal. Bagaimana saya melakukannya?

Rahul Vyas
sumber
5
Anda harus mengubah judul Anda: Anda meminta horizontal dalam pertanyaan dan vertikal dalam judul. Orang-orang akan menemukan pertanyaan Anda nanti di mesin telusur, jadi ini tetap penting 2 tahun kemudian :)
Julien
@RahulVyas Orang di atas ada benarnya. Mengubah judul akan mengurangi kebingungan bagi pemula yang sampai ke sini melalui mesin pencari (seperti saya;)).
SpacyRicochet
Telah mengedit judul atas nama pengepos. (Meskipun saat ini menunggu tinjauan sejawat sebelum hasil edit akan terlihat.)
Duncan Babbage

Jawaban:

125

Anda harus mengatur contentSizeproperti dari UIScrollView. Misalnya, jika Anda UIScrollViewmemiliki lebar 320 piksel (lebar layar), Anda dapat melakukan ini:

CGSize scrollableSize = CGSizeMake(320, myScrollableHeight);
[myScrollView setContentSize:scrollableSize];

The UIScrollViewakan kemudian hanya gulir vertikal, karena sudah dapat menampilkan segala sesuatu horizontal.

Dave DeLong
sumber
6
Hai. Solusi ini bekerja dengan sangat baik! Terima kasih untuk itu. Saya mencoba mengatur lebar statis ke 0. Bagi saya ini juga berfungsi. Saya tidak tahu apakah mungkin ada beberapa efek samping nanti. Tetapi jika seseorang tidak tahu ukurannya (yaitu kode universal untuk iPhone dan iPad) ini berfungsi dengan baik!
JackPearse
5
Saya pikir lebih baik melakukan CGSizeMake (0, myScrollableHeight), jadi pengguliran horizontal dinonaktifkan bahkan jika tidak semua subview ditampilkan.
LightNight
NB Menyetel salah satu dimensi ke 0 saat menggunakan paging akan menyebabkan VoiceOver mengumumkan nomor halaman sebagai "halaman 1 dari 1" terlepas dari nilai yang benar
josef
1
Alih-alih meneruskan lebar sebagai 320 hardcode, kita bisa meneruskan seperti: CGSize scrollableSize = CGSizeMake (self.scrollview.frame.size.width, myScrollableHeight); [myScrollView setContentSize: scrollableSize];
Mohit kumar
91

DIPERBARUI: (Setelah @EranMarom menunjukkan komentarnya)

Anda dapat menghentikan pengguliran horizontal atau pengguliran vertikal dalam ScrollViewDelegateMetode. Ini dia caranya,

Menghentikan Pengguliran Horizontal:

Jika Anda ingin menggulir secara horizontal, maka Anda perlu meningkatkan contentOffset.x. Mencegah yang menghentikan scrollview scroll dalam arah horizontal.

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.x = 0.0
}

Menghentikan Pengguliran Vertikal:

Jika Anda ingin menggulir secara vertikal, maka Anda perlu meningkatkan contentOffset.y. Mencegah yang menghentikan scrollview scroll ke arah vertikal.

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.y = 0.0
}

Kode di atas mencegah perubahan dalam xdan ydari a scrollview contentOffsetdan itu mengarah pada penghentian metode pengguliran scrollViewDidScroll:.

Dinesh Raja
sumber
1
Saya mempertimbangkan untuk downvoting karena jawaban ini tidak menjelaskan bahwa Anda baru saja memberikan kode dan hanya itu. Jawaban seperti itu tidak terlalu bagus. Jawaban bagus menjelaskan sendiri, sementara pengembang berpengalaman mungkin memahami pengembang baru ini mungkin tidak mengerti apa yang terjadi di sini. Belum mendapat suara negatif karena memberi kesempatan untuk berkembang.
Popeye
14
Ini semacam peretasan, tetapi berhasil ketika semuanya gagal. Jadi +1, tetapi gunakan hanya sebagai pilihan terakhir.
i_am_jorf
5
Saya juga menggunakan metode delegasi ini, tetapi saya mengganti body dengan one-liner, misalnya: scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y);untuk menonaktifkan scrolling horizontal. Saya merasa lebih mudah dibaca, lebih kecil, dan tidak ada gunanya melakukan tes untuk nol karena hampir tidak ada overhead dengan kode yang jarang menjalankan ini (yaitu beberapa puluh kali per detik maks).
Eselon
karena Anda mengubah contentOffset setelah "didscroll", tidak seperti sebelumnya 'willscroll', dan ini adalah solusi palu, tapi saya sendiri tidak downvote, karena 18 upvote dan jawabannya 75, jadi tidak layak untuk downvote
LolaRun
2
Lebih mudah lagi, gunakan scrollView.contentOffset.y = 0.0untuk menghentikan pengguliran vertikal dan scrollView.contentOffset.x = 0.0untuk menghentikan pengguliran horizontal, dalam scrollViewDidScroll()fungsi delegasi. Namun, saya percaya bahwa memastikan scrollView.contentSizesama dengan scrollView.frame.sizeadalah solusi yang lebih baik (benar). Lihat jawaban @danbeaulieu.
emem
11

sejak penggunaan iOS7

self.automaticallyAdjustsScrollViewInsets = NO;

// dan buat penggulung halaman Anda dengan 3 halaman

    self.pageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.pageView setContentSize:CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height)];
    [self.pageView setShowsVerticalScrollIndicator:NO];
    [self.pageView setPagingEnabled:YES];
    [self.view addSubview:self.pageView];
Mirko Brunner
sumber
Saya tidak berpikir ini akan menonaktifkan perilaku scrolling scrollview. Apakah itu??
Dinesh Raja
self.collectionView.pagingEnabled = YES;membantu saya menyelesaikan masalah dengan pengguliran yang mulus (bukan menyeret). Masalahnya ada pada metode scrollViewWillEndDragging:- targetContentOffset sama dengan scrollView.contentOffset dan logika deteksi halaman tidak berfungsi dengan benar.
sig
11

Solusi cepat

Buat dua outlet, satu untuk tampilan Anda dan satu untuk tampilan gulir Anda:

@IBOutlet weak var myView: UIView!
@IBOutlet weak var scrollView: UIScrollView!

Kemudian di viewDidLayoutSubviews Anda, Anda dapat menambahkan kode berikut:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: myView.frame.size.height)
scrollView.contentSize = scrollSize

Apa yang telah kita lakukan adalah mengumpulkan tinggi dan lebar tampilan dan menyetel ukuran konten scrollView agar sesuai. Ini akan menghentikan tampilan gulir Anda dari bergulir secara horizontal.


Lebih Banyak Pikiran:

CGSizeMake mengambil lebar & tinggi menggunakan CGFloats. Anda mungkin perlu menggunakan ketinggian UIScrollViews yang ada untuk parameter kedua. Yang akan terlihat seperti ini:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: scrollView.contentSize.height)
Dan Beaulieu
sumber
Bagaimana jika Anda tidak mengetahui tinggi atau lebarnya (perangkat universal)? @Beulieu
Lukesivi
@lukesIvi "myView.frame.width" secara dinamis menarik lebar dari IBOutlet "myView".
Dan Beaulieu
4

Dalam kasus saya, dengan Swift 4.2 Anda dapat menggunakan:

Nonaktifkan gulir vertikal:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = 0.0
}

Nonaktifkan gulir horizontal:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.x = 0.0
}
Ricardo
sumber
3

Anda dapat memilih tampilan, lalu di bawah Attributes Inspectorcentang User Interaction Enabled.

Pembuat kode221
sumber
3

Dalam kasus saya, lebar contentView lebih besar dari lebar UIScrollView dan itulah alasan pengguliran horizontal yang tidak diinginkan. Saya menyelesaikannya dengan mengatur lebar contentView sama dengan lebar UIScrollView.

Semoga bisa membantu seseorang

Gulfam Khan
sumber
@Nostradamus senang membantu
Gulfam Khan
0

Saya memiliki tableview contentInset yang disetel di viewDidLoad (seperti di bawah) yang menyebabkan pengguliran horizontal

self.tableView.contentInset = UIEdgeInsetsMake(0, 30, 0, 0);

Periksa apakah ada set tableview contentInset untuk alasan yang berbeda dan nonaktifkan

Naishta
sumber
0

Saya berjuang dengan ini untuk beberapa waktu mencoba berbagai saran tidak berhasil dalam utas ini dan lainnya.

Namun, di utas lain (tidak yakin di mana) seseorang menyarankan bahwa menggunakan batasan negatif pada UIScrollView berhasil untuknya.

Jadi saya mencoba berbagai kombinasi kendala dengan hasil yang tidak konsisten. Apa yang akhirnya berhasil bagi saya adalah menambahkan batasan leading dan trailing -32 ke scrollview dan menambahkan textview (tidak terlihat) dengan lebar 320 (dan di tengah).

PatriciaW
sumber
0

Coba ini:

CGSize scrollSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, scrollHeight);
[scrollView setContentSize: scrollSize];
Torongo
sumber
0

Nonaktifkan pengguliran horizontal dengan mengganti contentOffsetproperti di subkelas.

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: 0, y: newValue.y)
  }
}
iWheelBuy
sumber
0

Diperkenalkan di iOS 11 adalah properti baru di UIScrollView

var contentLayoutGuide: UILayoutGuide

Dokumentasi menyatakan bahwa Anda:

Gunakan panduan tata letak ini bila Anda ingin membuat batasan Tata Letak Otomatis yang terkait dengan area konten tampilan gulir.

Seiring dengan kendala AutoLayout lain yang Anda mungkin menambahkan Anda akan ingin membatasi widthAnchordari UIScrollView's contentLayoutGuideuntuk menjadi ukuran yang sama sebagai 'frame'. Anda dapat menggunakan frameLayoutGuide(juga diperkenalkan di iOS 11) atau lebar eksternal (seperti milik Anda superView.)

contoh:

NSLayoutConstraint.activate([
  scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: self.widthAnchor)
])

Dokumentasi: https://developer.apple.com/documentation/uikit/uiscrollview/2865870-contentlayoutguide

JMFR
sumber
-1

Setelah saya melakukannya, mengganti UIScrollView dengan UITableView hanya dengan 1 sel, itu berfungsi dengan baik.

Hola Soy Edu Feliz Navidad
sumber
1
Maaf, ini tidak menjawab pertanyaannya.
David
-1

Gunakan satu baris ini.

self.automaticallyAdjustsScrollViewInsets = NO;

Karthickkck
sumber