Oke, jawabannya tidak, tidak ada cara untuk melakukan ini tanpa subclass UICollectionViewFlowLayout.
Namun, membuat subclass sangat mudah bagi siapa saja yang membaca ini di masa mendatang.
Pertama saya mengatur panggilan subkelas MyCollectionViewFlowLayout
dan kemudian di pembuat antarmuka saya mengubah tata letak tampilan koleksi menjadi Kustom dan memilih subkelas tata letak aliran saya.
Karena Anda melakukannya dengan cara ini, Anda tidak dapat menentukan ukuran item, dll ... di IB jadi di MyCollectionViewFlowLayout.m saya punya ini ...
- (void)awakeFromNib
{
self.itemSize = CGSizeMake(75.0, 75.0);
self.minimumInteritemSpacing = 10.0;
self.minimumLineSpacing = 10.0;
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
}
Ini mengatur semua ukuran untuk saya dan arah gulir.
Kemudian ...
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalOffset = proposedContentOffset.x + 5;
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray *array = [super layoutAttributesForElementsInRect:targetRect];
for (UICollectionViewLayoutAttributes *layoutAttributes in array) {
CGFloat itemOffset = layoutAttributes.frame.origin.x;
if (ABS(itemOffset - horizontalOffset) < ABS(offsetAdjustment)) {
offsetAdjustment = itemOffset - horizontalOffset;
}
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
Ini memastikan bahwa pengguliran berakhir dengan margin 5.0 di tepi kiri.
Hanya itu yang perlu saya lakukan. Saya tidak perlu mengatur tata letak aliran dalam kode sama sekali.
targetContentOffsetForProposedContentOffset:withVelocity
tidak dipanggil untuk saya saat saya menggulir. Apa yang sedang terjadi?Solusi Dan cacat. Ini tidak menangani jentikan pengguna dengan baik. Kasus-kasus ketika pengguna menjentikkan cepat dan gulir tidak banyak bergerak, memiliki gangguan animasi.
Implementasi alternatif yang saya usulkan memiliki paginasi yang sama seperti yang diusulkan sebelumnya, tetapi menangani pengguna yang beralih antar halaman.
sumber
Versi cepat dari jawaban yang diterima.
Berlaku untuk Swift 5 .
sumber
Inilah implementasi saya di Swift 5 untuk paging berbasis sel vertikal :
Beberapa catatan:
itemSize
benar - benar cocok dengan ukuran item karena itu sering menjadi masalah, terutama saat menggunakancollectionView(_:layout:sizeForItemAt:)
, gunakan variabel khusus dengan itemSize sebagai gantinya.self.collectionView.decelerationRate = UIScrollView.DecelerationRate.fast
.Ini adalah versi horizontal (belum mengujinya secara menyeluruh jadi mohon maafkan jika ada kesalahan):
Kode ini didasarkan pada kode yang saya gunakan dalam proyek pribadi saya, Anda dapat memeriksanya di sini dengan mengunduhnya dan menjalankan target Contoh.
sumber
Meskipun jawaban ini sangat membantu saya, ada kedipan yang terlihat saat Anda menggesek cepat pada jarak yang kecil. Jauh lebih mudah untuk mereproduksinya di perangkat.
Saya menemukan bahwa ini selalu terjadi ketika
collectionView.contentOffset.x - proposedContentOffset.x
danvelocity.x
memiliki nyanyian yang berbeda.Solusi saya adalah memastikan bahwa
proposedContentOffset
lebih daricontentOffset.x
jika kecepatan positif, dan lebih sedikit jika negatif. Ada di C # tetapi harus cukup sederhana untuk diterjemahkan ke Tujuan C:Kode ini sedang digunakan
MinContentOffset
,MaxContentOffset
danSnapStep
yang seharusnya sepele untuk Anda tentukan. Dalam kasus saya, mereka ternyatasumber
Setelah pengujian yang lama saya menemukan solusi untuk diposisikan ke tengah dengan lebar sel khusus (setiap sel memiliki lebar yang berbeda) yang memperbaiki kedipan. Silakan perbaiki skripnya.
sumber
lihat jawaban ini dari Dan Abramov berikut ini versi Swift
atau intinya di sini https://gist.github.com/katopz/8b04c783387f0c345cd9
sumber
Untuk siapapun yang mencari solusi yang ...
collectionView.contentInset
(dan safeArea di iPhone X)lalu silahkan lihat dibawah ...
sumber
Inilah solusi Swift saya pada tampilan koleksi yang bergulir secara horizontal. Sederhana, manis, dan menghindari kedipan.
sumber
itemSize
??pageWidth()
harus digunakanminimumLineSpacing
karena menggulung secara horizontal. Dan dalam kasus saya, saya memiliki tampilancontentInset
untuk koleksi sehingga sel pertama dan terakhir bisa dipusatkan, jadi saya gunakanlet xOffset = pageWidth() * index - collectionView.contentInset.left
.masalah kecil yang saya temui saat menggunakan targetContentOffsetForProposedContentOffset adalah masalah dengan sel terakhir yang tidak menyesuaikan sesuai dengan poin baru yang saya kembalikan.
Saya menemukan bahwa CGPoint yang saya kembalikan memiliki nilai Y yang lebih besar daripada yang diizinkan, jadi saya menggunakan kode berikut di akhir implementasi targetContentOffsetForProposedContentOffset saya:
hanya untuk membuatnya lebih jelas ini adalah implementasi tata letak lengkap saya yang hanya meniru perilaku paging vertikal:
mudah-mudahan ini akan menghemat waktu dan sakit kepala seseorang
sumber
Saya lebih suka mengizinkan pengguna membolak-balik beberapa halaman. Jadi inilah versi saya
targetContentOffsetForProposedContentOffset
(yang berdasarkan jawaban DarthMike) untuk tata letak vertikal .sumber
Jawaban Fogmeisters berhasil untuk saya kecuali saya menggulir ke akhir baris. Sel saya tidak pas dengan rapi di layar sehingga akan bergulir ke ujung dan melompat kembali dengan sentakan sehingga sel terakhir selalu tumpang tindih dengan tepi kanan layar.
Untuk mencegahnya, tambahkan baris kode berikut di awal metode targetcontentoffset
sumber
Kode @ André Abu
Versi Swift3
sumber
Cepat 4
Solusi termudah untuk tampilan koleksi dengan sel satu ukuran (gulir horizontal):
sumber
Solusi yang lebih singkat (dengan asumsi Anda sedang menyimpan atribut tata letak Anda):
Untuk menempatkan ini dalam konteks:
sumber
Untuk memastikannya berfungsi dalam versi Swift (swift 5 sekarang), saya menggunakan jawabannya dari @ André Abreu, saya menambahkan beberapa informasi lagi:
Saat membuat subkelas UICollectionViewFlowLayout, "override func awakeFromNib () {}" tidak bekerja (tidak tahu mengapa). Sebagai gantinya, saya menggunakan "override init () {super.init ()}"
Ini kode saya yang diletakkan di kelas SubclassFlowLayout: UICollectionViewFlowLayout {}:
Setelah membuat subclass, pastikan untuk meletakkan ini di ViewDidLoad ():
sumber
Bagi mereka yang mencari solusi di Swift:
sumber
Ini adalah demo untuk paging dengan sel (saat menggulir cepat, tidak melewati satu atau lebih sel): https://github.com/ApesTalk/ATPagingByCell
sumber