Mevcut sayfayı alma


98

Kaydırma görünümümde, görüntülenmekte olan geçerli sayfayı almak istiyorum (belki sayfa doğru terim olmayabilir). Bunu tutan herhangi bir değişken bulamıyorum. Ancak, gösterge şu anda kaydırma görünümünün hangi alt görünümünün görüntülendiğini gösterebildiğinden, bunun bir yerde tutulması gerektiğini düşünüyorum.

Bu tamamen bizden mi gizli yoksa ona erişmem için bir yol var mı?

Yanıtlar:


263

UIScrollViewMevcut sayfa için özellik yok . Bunu şu şekilde hesaplayabilirsiniz:

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

En yakın sayfaya yukarı veya aşağı yuvarlamak istiyorsanız, şunu kullanın:

CGFloat width = scrollView.frame.size.width;
NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;

7
UIScrollViewDelegateKullanıcı ekranı kaydırdığında geçerli sayfayı almak için kullanmayı unutmayın !
Sam Spencer

Bu, rotasyonla uğraşırken sorun yaşayabilir.
Jason McCreary

lütfen hızlı sürümü ekleyin
fnc12

1
Bu her zaman işe yaramaz, bazen çerçeve genişliği yanlıştır.
Rodrigo Ruiz

Bu her zaman işe yaramıyor. Bazen sayfayı 0 olarak alıyorum, bu benim durumumda yanlış.
Sneha

32

Bu kodu kullanmanızı şiddetle tavsiye ederim

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

ancak bu kodu kullanırsanız, görünümünüzün indexOfPage'in size verdiği sayfada olması gerekmez. Çünkü ben de bu kodu sadece bu yöntemde kullanmanızı tavsiye ediyorum.

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

ScrollView'unuz kaydırmayı bitirdiğinde ve sayfanızın numarasının gerçekten keskin olması için çağrılan

ScrollView'ınızı bu kodla etkinleştirilmiş olarak ayarlamanızı tavsiye ederim

[scrollView setPagingEnabled:YES];

Sonunda böyle görünmeli

-(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
}

iOS7 cihazında çalışmıyor (XCODE 6.2 ile derlendi) contentOffset.x, scrollViewDidEndDecelerating olduğunda 640 yerine 639'a eşittir (nedenini sorma ...). user363349 yanıtı doğru: dönüş katı ((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
Vassily

Bu her zaman işe yaramıyor. Bazen sayfayı 0 olarak alıyorum, bu durum benim durumumda yanlış.
Sneha

30

Hızlı olarak bunu uzantı olarak yapardım:

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

O zaman arayın:

scrollView.currentPage

10
Neredeyse mükemmel, benim
dünyamda

12

Yukarıdaki gibi ama kategori olarak


@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

6
Bu abartıldı, sadece dönüş turunu kullanın (self.contentOffset.x / self.frame.size.width); Çok daha basit ve anlaşılması daha kolay ..
Leonard Pauli

-1 @LeonardPauli. Yukarıdaki uygulama,% 50'den fazla görünür olan sayfayı döndürür. Saf uygulama, yalnızca kaydırma görünümünün alt görünümü tüm kaydırma görünümü sınırlarını işgal ettiğinde sayfa değerini değiştirir.
kullanıcı

1
@user İlk olarak, floor () her zaman aşağı yuvarlar ve ondalık kısım> = 5 ise round () yukarı yuvarlar, aksi takdirde aşağı yuvarlar. Bununla birlikte, kat (a) = yuvarlak (a-0.5). Biraz basit cebir yapalım. kat ((ab / 2) / b) +1 = kat (a / b-0.5) +1 = yuvarlak (a / b-0.5-0.5) +1 = yuvarlak (a / b-1) +1 = yuvarlak ( a / b). Bak! Kat ((ab / 2) / b) +1 = yuvarlak (a / b) gibi görünüyor! Matematiksel.
Leonard Pauli

Ama evet, eğer herhangi bir nedenle onun yerine yeri kullansaydım, o zaman çok haklıydın! ;)
Leonard Pauli

9

Başka bir yol :

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

6

Sadece geçerli ofseti sayfa boyutuna bölün:

CGFloat pageNum = (int)(scrollView.contentOffset.x / scrollView.frame.size.width);

11
İnt'e çevrim ve ardından bir float'a atama? Neden pageNum int yapmıyorsunuz;)
Klaas

6

Zaten burada bazı iyi cevaplar var. Bununla birlikte, içeriğin bir sayfaya tam olarak sığmadığı senaryolar için - ve benim gibi sonucu a için kullanmak istiyorsanız UIPageControl, o zaman ceilişlevi kullanmak çok önemlidir .

"Dört ve biraz" içerik sayfamın olduğu bir örneği ele alalım.

Bunu şu anki gerçek hayat örneğime dayandıracağım. İçerik boyutu genişliği 3140 puntodur. Koleksiyon görünümümün çerçeve boyutuna göre sayfa genişliği 728.

Yani sayfa sayısı şuna eşittir:

 3140 / 728 = 4.313 

Benim numberOfPagesbeş olacağım. Bunların dördü bir bütün olarak gösterilecek ve sonuncusu - sayfa beş - kalan 0.313içeriğin gösterecektir .

Şimdi, numberOfPagesbeş olmak, sayfa indekslerinin 0, 1, 2, 3 ve 4 olacağı anlamına gelir.

Sağa kaydırdığımda, son ofsete doğru sayfalandırdığımda, scrollViewDidEndDeceleratingyöntem 2412'lik bir son X uzaklığı veriyor.

Yuvarlama hesaplamasının uygulanması:

2412 / 728 = 3.313 then rounded = 3

Bu yanlış. Göreli konumla görüntüleyen sayfa şu şekilde olmalıdır:

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

Aşağıdakileri kullanarak doğru hesaplama 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
}

4

Aoakenfo'nun çözümü harika, bu, kodunuzu scrollViewDidScroll ve PageController işleviyle birleştiren başka bir çözümdür.

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    if (sender == self.scroll) {
        int pageNum = (int)(self.scrPage.contentOffset.x / self.scrPage.frame.size.width);
        self.pagecontroller.currentPage =pageNum;
    }
}

1
Bu açgözlü, tembel değil ... MVC de değil. Çok daha basit bir yol, geçerli Sayfayı kaydırmada geçersiz kılmak ve yalnızca istendiğinde ayarlamaktır ... tümü UIScrollView'daki bir alt sınıftan veya kategoriden

4

Hızlı için sadece bunu kullanırdım

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

Oldukça basittir, temelde kaydırma görünümü x konumunu alır, kaydırma görünümü genişliğine böler ve sonra yuvarlar.


3

XCode 7.x swift 2.x'te şunları yapabilirsiniz:

//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
    }
}

2

Bunu birkaç uygulamamızdan çıkardım ...

- (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;
}

Tam kaynak burada


1

Bir UIPageControl kullanıyor musunuz? Eğer öyleyse, bunun bir currentPageözelliği var. Değilse, scrollView ofsetinden sayfa dizinini hesaplamanız gerekeceğini düşünüyorum.


0

Herhangi biri Xamarin için C # 'da yapmanın bir yolunu arıyorsanız

    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);
    }

Bu alıcı ve Ayarlayıcı size geçerli sayfayı sağlamalı ve belirtilen sayfaya gitmenize izin vermelidir


0

Swift 5.1+ UIScrollView uzantısı (dönüş anahtar sözcüğünü atlamak)

extension UIScrollView {

    var currentPage: Int {
        Int(round(self.contentOffset.x / self.frame.width))
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.