Отримання поточної сторінки


97

У своєму вікні прокрутки я хочу отримати поточну сторінку, що відображається (можливо, сторінка не є правильним терміном). Я не можу знайти жодну змінну, яка б це стосувалась. Але я думаю, що його треба десь провести, оскільки індикатор здатний показувати, який підвид перегляду прокрутки наразі відображається.

Це повністю приховано від нас або є спосіб отримати доступ до мене?

Відповіді:


263

Немає UIScrollViewвластивості для поточної сторінки. Ви можете розрахувати це за допомогою:

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

Якщо ви хочете округлити вгору або вниз до найближчої сторінки, використовуйте:

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

7
Не забудьте скористатися, UIScrollViewDelegateщоб отримати поточну сторінку, коли користувач прокручує!
Сем Спенсер

Це може мати проблеми при обертанні.
Джейсон МакКрірі

додайте швидку версію
fnc12,

1
Це не завжди працює, іноді ширина кадру неправильна.
Родріго Руїз

Це працює не завжди. Іноді я отримую сторінку як 0, що в моєму випадку неправильно.
Sneha

32

Я дуже рекомендую вам використовувати цей код

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

але якщо ви використовуєте цей код, ваш погляд не повинен бути точно на тій сторінці, яку дає indexOfPage. Це тому, що я також рекомендую використовувати цей код тільки в цьому методі

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

який називається, коли ваш scrollView закінчує прокрутку і щоб номер вашої сторінки був дуже чітким

Я рекомендую встановити ваш scrollView на сторінку, включену з цим кодом

[scrollView setPagingEnabled:YES];

Отже, нарешті, це має виглядати саме так

-(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 (компільований з XCODE 6.2) contentOffset.x дорівнює 639 замість 640 (не питайте мене, чому ...), коли scrollViewDidEndDecelerating. відповідь user363349 правильна: повернення поверху ((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
Василь

Це працює не завжди. Іноді я отримую сторінку як 0, що в моєму випадку неправильно.
Sneha

30

Я швидко зробив би це в розширення:

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

Тоді просто зателефонуйте:

scrollView.currentPage

10
Майже ідеально, мені довелося зняти +1 наприкінці, оскільки в моєму світі все на нулі
mvandillen

12

Як вище, але як категорія


@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
Це перестаралося, просто використовуйте return round (self.contentOffset.x / self.frame.size.width); Набагато простіше і легше зрозуміти ..
Леонард Паулі

-1 @LeonardPauli. Вищеописана реалізація повертає сторінку, яку видно понад 50%. Наївна реалізація змінює значення сторінки лише тоді, коли підвид перегляду прокрутки займає всі межі перегляду прокрутки.
користувач

1
@user По-перше, підлогу () округляє завжди вниз, а круглий () округляє вгору, якщо десяткова частина> = 5, в іншому випадку вниз. За словами, підлога (a) = кругла (a-0,5). Давайте зробимо просту алгебру. пол ((ab / 2) / b) +1 = підлога (a / b-0.5) +1 = кругла (a / b-0.5-0.5) +1 = кругла (a / b-1) +1 = кругла ( а / б). Подивіться! Здається, підлога ((ab / 2) / b) +1 = кругла (a / b)! Математичний.
Леонард Паулі

Але так, якби я чомусь замість цього використовував би підлогу, то ти був би абсолютно прав! ;)
Леонард Паулі

8

Інший спосіб :

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

6

Просто поділіть поточний зсув на розмір сторінки:

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

11
Лиття до int, а потім присвоєння float? Чому б не зробити сторінкуNum int також;)
Клаас

6

Тут вже є кілька хороших відповідей. Однак для сценаріїв, коли вміст не вписується точно в сторінку - і якщо, як я, ви хочете використовувати результат для UIPageControl, то важливо використовуватиceil функцію.

Візьмемо приклад, коли у мене є "вміст чотирьох і трохи" сторінок.

Я буду грунтуватися на цьому на прикладі свого реального життя. Ширина розміру вмісту становить 3140 балів. Залежно від розміру кадру моєї колекції, ширина сторінки становить 728.

Отже кількість сторінок дорівнює:

 3140 / 728 = 4.313 

Моїй numberOfPagesбуде п’ять. Чотири з яких будуть показані в повному обсязі, а остання з яких - сторінка п’ята - покаже те, що залишилося 0.313за змістом.

Тепер, numberOfPagesякщо п'ять, означає, що індекси сторінок будуть 0, 1, 2, 3 і 4.

Коли я проведу пальцем праворуч, переходячи до остаточного зміщення, scrollViewDidEndDecelerating метод дає остаточне зміщення X 2412.

Застосування розрахунку округлення:

2412 / 728 = 3.313 then rounded = 3

Це неправильно. Користувач сторінки переглядає зі зміщенням:

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

Правильний розрахунок, використовуючи 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

Для швидкого я б просто скористався цим

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

Досить просто, він в основному займає позицію scrollview x, ділить його на ширину scrollview, потім округляє його.


3

У xCode 7.x swift 2.x ви можете:

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

3

Рішення Aoakenfo дивовижне, це ще одне рішення, що поєднує ваш код з функцією scrollViewDidScroll і 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;
    }
}

1
Це жадібно, не ліниво ... Це також не MVC. Набагато простіший спосіб - визнати поточну сторінку прокруткою недійсною та встановити її лише тоді, коли її вимагають ... все з підкласу або категорії на UIScrollView

2

Я витягнув це з пари наших додатків ...

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

Повне джерело тут


1

Використовуєте UIPageControl? Якщо так, то це маєcurrentPage властивість. Якщо ні, то, я думаю, вам потрібно буде обчислити індекс сторінки за зміщенням scrollView.


0

Якщо хтось шукає способу в C # для 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);
    }

Цей геттер та сетер повинен надавати вам поточну сторінку, а також дозволяти вам прокручувати до вказаної сторінки


0

Swift 5.1+ розширення UIScrollView (опущення повернення ключового слова)

extension UIScrollView {

    var currentPage: Int {
        Int(round(self.contentOffset.x / self.frame.width))
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.