Mendapatkan halaman saat ini

97

Dalam tampilan gulir saya, saya ingin mendapatkan halaman saat ini yang sedang ditampilkan (mungkin halaman bukanlah istilah yang benar). Saya tidak dapat menemukan variabel apa pun yang menahan ini. Tapi saya pikir itu harus diadakan di suatu tempat, karena indikator dapat menunjukkan sub-tampilan mana dari tampilan gulir yang sedang ditampilkan.

Apakah ini sepenuhnya disembunyikan dari kita atau adakah cara bagi saya untuk mengaksesnya?

TheNeil
sumber

Jawaban:

263

Tidak ada UIScrollViewproperti untuk halaman ini. Anda dapat menghitungnya dengan:

int page = scrollView.contentOffset.x / scrollView.frame.size.width;

Jika Anda ingin membulatkan ke atas atau ke bawah ke halaman terdekat, gunakan:

CGFloat width = scrollView.frame.size.width;
NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;
AlexVogel
sumber
7
Jangan lupa untuk menggunakan UIScrollViewDelegateuntuk mendapatkan halaman saat ini ketika pengguna menggulir!
Sam Spencer
Ini mungkin mengalami masalah saat berurusan dengan rotasi.
Jason McCreary
tolong tambahkan versi cepat
fnc12
1
Ini tidak selalu berhasil, terkadang lebar bingkai salah.
Rodrigo Ruiz
Ini tidak selalu berhasil. Terkadang saya mendapatkan halaman sebagai 0 yang salah dalam kasus saya.
Sneha
32

Saya sangat menyarankan Anda untuk menggunakan kode ini

int indexOfPage = scrollView.contentOffset.x / scrollView.frame.size.width;

tetapi jika Anda menggunakan kode ini, tampilan Anda tidak harus persis pada halaman yang diberikan indexOfPage. Itu karena saya juga menyarankan Anda untuk menggunakan kode ini hanya dalam metode ini

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{}

yang dipanggil saat scrollView Anda selesai bergulir dan agar jumlah halaman Anda benar-benar tajam

Saya menyarankan Anda untuk mengatur scrollView Anda ke halaman diaktifkan dengan kode ini

[scrollView setPagingEnabled:YES];

Jadi akhirnya akan terlihat seperti itu

-(void) methodWhereYouSetYourScrollView
{
   //set scrollView
   [scrollView setPagingEnabled:YES];
   scrollView.delegate = self;
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
   int indexOfPage = scrollView.contentOffset.x / scrollView.frame.size.width;
   //your stuff with index
}
Jiří Zahálka
sumber
tidak berfungsi pada perangkat iOS7 (dikompilasi dengan XCODE 6.2) contentOffset.x sama dengan 639 bukannya 640 (jangan tanya saya kenapa ...) saat scrollViewDidEndDecelerating. jawaban pengguna363349 benar: return floor ((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
Vassily
Ini tidak selalu berhasil. Terkadang saya mendapatkan halaman sebagai 0 yang salah dalam kasus saya.
Sneha
30

Dengan cepat saya akan melakukannya dalam ekstensi:

extension UIScrollView {
    var currentPage:Int{
        return Int((self.contentOffset.x+(0.5*self.frame.size.width))/self.frame.width)+1
    }
}

Kemudian panggil saja:

scrollView.currentPage
Andrius Steponavičius
sumber
10
Hampir sempurna, saya harus menghapus +1 di akhir karena semuanya nol berbasis di dunia saya
mvandillen
12

Seperti di atas, tetapi sebagai kategori


@interface UIScrollView (CurrentPage)
-(int) currentPage;
@end
@implementation UIScrollView (CurrentPage)
-(int) currentPage{
    CGFloat pageWidth = self.frame.size.width;
    return floor((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
}
@end
pengguna363349
sumber
6
Itu berlebihan, cukup gunakan putaran kembali (self.contentOffset.x / self.frame.size.width); Jauh lebih sederhana dan lebih mudah untuk dipahami ..
Leonard Pauli
-1 @Leironis Penerapan di atas mengembalikan halaman yang terlihat lebih dari 50%. Penerapan naif hanya mengubah nilai halaman jika subview scrollview memenuhi seluruh batas scrollview.
pengguna
1
@user Pertama, floor () membulatkan selalu ke bawah, dan round () membulatkan ke atas jika bagian desimal> = 5, jika tidak ke bawah. Dengan demikian, lantai (a) = bulat (a-0,5). Mari kita lakukan aljabar sederhana. lantai ((ab / 2) / b) +1 = lantai (a / b-0,5) +1 = bulat (a / b-0,5-0,5) +1 = bulat (a / b-1) +1 = bulat ( a / b). Lihat! Sepertinya lantai ((ab / 2) / b) +1 = bulat (a / b)! Matematika.
Leonard Pauli
Tapi ya, jika saya karena alasan tertentu menggunakan lantai sebagai gantinya, maka Anda akan benar! ;)
Leonard Pauli
8

Cara lain :

extension MyViewController: UIScrollViewDelegate {
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let width = scrollView.frame.width
        let page = Int(round(scrollView.contentOffset.x/width))
        print("CurrentPage:\(page)")
    }
}
Hemang
sumber
6

Bagi saja offset saat ini dengan ukuran halaman:

CGFloat pageNum = (int)(scrollView.contentOffset.x / scrollView.frame.size.width);
aoakenfo
sumber
11
Mentransmisikan ke int dan kemudian menetapkan ke float? Mengapa tidak membuat pageNum int juga;)
Klaas
6

Sudah ada beberapa jawaban bagus di sini. Namun, untuk skenario di mana konten tidak pas persis dengan halaman - dan jika seperti saya Anda ingin menggunakan hasilnya untuk UIPageControl, maka penting untuk menggunakanceil fungsi tersebut.

Mari kita ambil contoh di mana saya memiliki "empat dan sedikit" halaman konten.

Saya akan mendasarkan ini pada contoh kehidupan nyata saya saat ini. Lebar ukuran konten adalah 3140 poin. Berdasarkan ukuran bingkai tampilan koleksi saya, lebar halaman adalah 728.

Jadi jumlah halaman sama dengan:

 3140 / 728 = 4.313 

Saya numberOfPagesakan menjadi lima. Empat di antaranya akan ditampilkan secara keseluruhan, dan yang terakhir - halaman lima - akan menampilkan konten yang tersisa 0.313.

Sekarang, numberOfPagesmenjadi lima berarti indeks halaman akan menjadi 0, 1, 2, 3, dan 4.

Saat saya menggesek ke kanan, paging menuju offset akhir, file scrollViewDidEndDecelerating metode ini memberikan offset X terakhir 2412.

Menerapkan perhitungan pembulatan:

2412 / 728 = 3.313 then rounded = 3

Itu salah. Pengguna halaman yang melihat dengan offset harus:

Offset / Page User Is Viewing
0        0
728      1
1456     2
2184     3
2412     4

Perhitungan yang benar menggunakan ceil:

private func pageForOffset(offset:CGFloat, pageWidth width:CGFloat) -> Int
{
    let page = Int(ceil(offset / width))
    NSLog("\(__FUNCTION__) offset \(offset) width \(width) page \(page) ")
    return page
}
Max MacLeod
sumber
4

Untuk cepat saya hanya akan menggunakan ini

    let width = scrollView.frame.width
    let page = round(scrollView.contentOffset.x/width)

Cukup mudah, pada dasarnya ini mengambil posisi scrollview x, membaginya dengan lebar scrollview, lalu membulatkannya.

neptunes
sumber
3

Di xCode 7.x swift 2.x Anda dapat melakukan:

//MARK: - ScrollView Extensions
// Get the current page number
extension UIScrollView {
    var currentPage: Int {
        return Int(round(self.contentOffset.x / self.bounds.size.width))
    }

// If you have reversed offset (start from contentSize.width to 0)
    var reverseCurrentPage: Int {
        return Int(round((contentSize.width - self.contentOffset.x) / self.bounds.size.width))-1
    }
}
Alessandro Ornano
sumber
3

Solusi Aoakenfo luar biasa, ini adalah solusi lain yang menggabungkan kode Anda dengan fungsi scrollViewDidScroll dan PageController

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    if (sender == self.scroll) {
        int pageNum = (int)(self.scrPage.contentOffset.x / self.scrPage.frame.size.width);
        self.pagecontroller.currentPage =pageNum;
    }
}
pabloverd
sumber
1
Ini serakah, tidak malas ... Ini juga bukan MVC. Cara yang jauh lebih sederhana adalah dengan membatalkan currentPage pada scroll, dan menyetelnya hanya jika diminta ... semua dari subclass atau kategori di UIScrollView
2

Saya mengekstrak ini dari beberapa aplikasi kami ...

- (NSInteger)currentPage
{
    if (0 == self.frame.size.width) {
        NSLog(@"frame width == 0!");
        return 0;
    }
    if (! self.currentPageValid) {
        _currentPage = round(self.contentOffset.x / self.frame.size.width);
        self.currentPageValid = YES;
    }
    return _currentPage;
}

Sumber lengkapnya di sini


sumber
1

Apakah Anda menggunakan UIPageControl? Jika demikian, ini memiliki currentPageproperti. Jika tidak, saya pikir Anda harus menghitung indeks halaman dari offset scrollView.

Renger
sumber
0

Jika Ada yang Mencari cara melakukan di C # untuk Xamarin

    public int CurrentIndex
    {
        get => (int)Math.Round(this.scrollView.ContentOffset.X / this.scrollView.Frame.Width);
        set => this.scrollView.ScrollRectToVisible(new CGRect(new CGPoint(this.scrollView.Frame.Size.Width * value, 0), this.scrollView.Frame.Size), true);
    }

Getter dan Setter ini harus memberikan Anda halaman saat ini juga memungkinkan Anda menggulir ke halaman yang ditentukan

soan saini
sumber
0

Swift 5.1+ ekstensi UIScrollView (Menghilangkan kata kunci kembali)

extension UIScrollView {

    var currentPage: Int {
        Int(round(self.contentOffset.x / self.frame.width))
    }
}
Diego Carrera
sumber