Lấy trang hiện tại


97

Trong chế độ xem cuộn của tôi, tôi muốn lấy trang hiện tại đang được hiển thị (có thể trang không phải là thuật ngữ chính xác). Tôi không thể tìm thấy bất kỳ biến nào chứa điều này. Nhưng tôi nghĩ nó phải được giữ ở đâu đó, vì chỉ báo có thể hiển thị chế độ xem phụ nào của chế độ xem cuộn hiện đang được hiển thị.

Điều này có bị ẩn với chúng tôi hoàn toàn không hay có cách nào để tôi truy cập vào nó?

Câu trả lời:


263

Không có UIScrollViewtài sản cho trang hiện tại. Bạn có thể tính toán nó với:

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

Nếu bạn muốn làm tròn lên hoặc xuống trang gần nhất, hãy sử dụng:

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

7
Đừng quên sử dụng UIScrollViewDelegateđể lấy trang hiện tại khi người dùng cuộn!
Sam Spencer

Điều này có thể có vấn đề khi xử lý xoay.
Jason McCreary

xin vui lòng thêm nhanh chóng phiên bản
fnc12

1
Điều này không phải lúc nào cũng hiệu quả, đôi khi chiều rộng khung hình bị sai.
Rodrigo Ruiz

Điều này không phải lúc nào cũng hoạt động. Đôi khi tôi nhận được trang là 0, điều này là sai trong trường hợp của tôi.
Sneha

32

Tôi thực sự khuyên bạn nên sử dụng mã này

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

nhưng nếu bạn sử dụng mã này, chế độ xem của bạn không cần phải nằm chính xác trên trang mà indexOfPage cung cấp cho bạn. Đó là bởi vì tôi cũng khuyên bạn chỉ nên sử dụng mã này trong phương pháp này

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

được gọi khi scrollView của bạn cuộn xong và để có số lượng trang của bạn thực sự sắc nét

Tôi khuyên bạn nên đặt Chế độ xem cuộn của mình thành trang được bật bằng mã này

[scrollView setPagingEnabled:YES];

Vì vậy, cuối cùng nó sẽ giống như vậy

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

không hoạt động trên thiết bị iOS7 (được biên dịch với XCODE 6.2) contentOffset.x bằng 639 thay vì 640 (đừng hỏi tôi tại sao ...) khi scrollViewDidEndDecelerating. câu trả lời của user363349 là đúng: return floor ((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
Vassily

Điều này không phải lúc nào cũng hoạt động. Đôi khi tôi nhận được trang là 0, điều này là sai trong trường hợp của tôi.
Sneha

30

Trong thời gian nhanh chóng, tôi sẽ làm điều đó trong phần mở rộng:

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

Sau đó, chỉ cần gọi:

scrollView.currentPage

10
Gần như hoàn hảo, tôi đã phải tháo 1 lúc kết thúc kể từ khi mọi thứ đều không có trụ sở tại thế giới của tôi
mvandillen

12

Như trên nhưng là một danh mục


@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
Đã quá hạn, chỉ cần sử dụng vòng quay trở lại (self.contentOffset.x / self.frame.size.width); Nhiều đơn giản và dễ hiểu ..
Leonard Pauli

-1 @LeonardPauli. Việc triển khai trên trả về trang hiển thị hơn 50%. Việc triển khai ngây thơ chỉ thay đổi giá trị trang khi lượt xem phụ của lượt xem cuộn chiếm toàn bộ giới hạn của lượt xem cuộn.
người dùng

1
@user Đầu tiên, floor () luôn làm tròn xuống, và round () làm tròn lên nếu phần thập phân> = 5, ngược lại là giảm. Như đã nói, sàn (a) = round (a-0,5). Hãy làm một số đại số đơn giản. sàn ((ab / 2) / b) +1 = sàn (a / b-0,5) +1 = vòng (a / b-0,5-0,5) +1 = vòng (a / b-1) +1 = vòng ( a / b). Nhìn! Có vẻ như sàn ((ab / 2) / b) +1 = round (a / b)! Tính toán học.
Leonard Pauli,

Nhưng đúng vậy, nếu vì lý do nào đó tôi đã sử dụng sàn thay thế, thì bạn đã hoàn toàn đúng! ;)
Leonard Pauli

8

Một cách khác :

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

6

Chỉ cần chia độ lệch hiện tại cho kích thước trang:

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

11
Truyền tới int và sau đó gán cho float? Tại sao không làm pageNum int cũng;)
Klaas

6

Đã có một số câu trả lời hay ở đây. Tuy nhiên, đối với các tình huống mà nội dung không vừa chính xác với một trang - và nếu giống như tôi, bạn muốn sử dụng kết quả cho một UIPageControl, thì điều cần thiết là sử dụng ceilhàm.

Hãy lấy một ví dụ mà tôi có trang nội dung "bốn và một chút".

Tôi sẽ căn cứ vào ví dụ thực tế hiện tại của mình. Chiều rộng kích thước nội dung là 3140 điểm. Dựa trên kích thước khung xem bộ sưu tập của tôi, chiều rộng trang là 728.

Vì vậy, số trang bằng:

 3140 / 728 = 4.313 

My numberOfPagessắp lên năm. Bốn trong số đó sẽ hiển thị toàn bộ, và trang cuối cùng - trang năm - sẽ hiển thị phần 0.313nội dung còn lại .

Bây giờ, numberOfPageslà năm có nghĩa là các chỉ số trang sẽ là 0, 1, 2, 3 và 4.

Khi tôi vuốt sang phải, phân trang theo hướng bù đắp cuối cùng, scrollViewDidEndDeceleratingphương pháp này cung cấp độ lệch X cuối cùng là 2412.

Áp dụng phép tính làm tròn:

2412 / 728 = 3.313 then rounded = 3

Điều đó không chính xác. Người dùng trang đang xem theo độ lệch phải là:

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

Phép tính đúng bằng cách sử dụng 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

Để nhanh chóng, tôi sẽ chỉ sử dụng cái này

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

Khá đơn giản, về cơ bản, nó lấy vị trí scrollview x, chia nó cho chiều rộng scrollview, sau đó làm tròn nó.


3

Trong xCode 7.x swift 2.x bạn có thể làm:

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

Giải pháp của Aoakenfo thật tuyệt vời, đây là một giải pháp khác kết hợp mã của bạn với chức năng scrollViewDidScroll và 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
Đây là tham lam, không phải lười biếng ... Nó cũng không phải là MVC. Một cách đơn giản hơn nhiều là để làm mất hiệu lực currentPage trên cuộn, và đặt nó chỉ khi nó được yêu cầu ... tất cả từ một lớp con hoặc loại trên UIScrollView

2

Tôi đã trích xuất điều này từ một vài ứng dụng của chúng tôi ...

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

Nguồn đầy đủ tại đây


1

Bạn có đang sử dụng UIPageControl không? Nếu vậy, điều này có một currentPagetài sản. Nếu không, tôi nghĩ bạn sẽ cần tính toán chỉ số trang từ phần bù của scrollView.


0

Nếu có ai đang tìm kiếm cách làm trong C # cho 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 và Setter này sẽ cung cấp cho bạn trang hiện tại cũng như cho phép bạn cuộn đến trang được chỉ định


0

Tiện ích mở rộng Swift 5.1+ UIScrollView (Bỏ qua từ khóa trả về)

extension UIScrollView {

    var currentPage: Int {
        Int(round(self.contentOffset.x / self.frame.width))
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.