รับหน้าปัจจุบัน


98

ในมุมมองแบบเลื่อนของฉันฉันต้องการรับเพจปัจจุบันที่กำลังแสดงอยู่ (เพจอาจไม่ใช่คำที่ถูกต้อง) ฉันไม่พบตัวแปรที่เก็บค่านี้ แต่ฉันคิดว่ามันต้องถูกจัดไว้ที่ไหนสักแห่งเนื่องจากตัวบ่งชี้สามารถแสดงได้ว่ากำลังแสดงมุมมองย่อยของมุมมองเลื่อนใดอยู่

สิ่งนี้ถูกซ่อนจากเราอย่างสมบูรณ์หรือมีวิธีให้ฉันเข้าถึงได้หรือไม่?

คำตอบ:


264

ไม่มี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เพื่อรับหน้าปัจจุบันเมื่อผู้ใช้เลื่อน!
Sam Spencer

สิ่งนี้อาจมีปัญหาเมื่อต้องจัดการกับการหมุน
Jason McCreary

โปรดเพิ่มรุ่นที่รวดเร็ว
fnc12

1
วิธีนี้ไม่ได้ผลเสมอไปบางครั้งความกว้างของเฟรมไม่ถูกต้อง
Rodrigo Ruiz

สิ่งนี้ไม่ได้ผลเสมอไป บางครั้งฉันได้รับหน้าเป็น 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 ถูกต้อง: return floor ((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
Vassily

สิ่งนี้ไม่ได้ผลเสมอไป บางครั้งฉันได้รับหน้าเป็น 0 ซึ่งผิดในกรณีของฉัน
Sneha

31

อย่างรวดเร็วฉันจะทำในส่วนขยาย:

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); ง่ายกว่าและเข้าใจง่ายกว่ามาก ..
Leonard Pauli

-1 @LeonardPauli. การใช้งานข้างต้นส่งคืนหน้าที่สามารถมองเห็นได้มากกว่า 50% การใช้งานแบบไร้เดียงสาจะเปลี่ยนค่าของเพจเมื่อมุมมองย่อยของ scrollview อยู่ในขอบเขตของ scrollview ทั้งหมด
ผู้ใช้

1
@user ประการแรก floor () ปัดลงเสมอและปัดเศษ () ขึ้นหากส่วนทศนิยม> = 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 = รอบ ( a / b) ดู! ดูเหมือนว่าพื้น ((ab / 2) / b) +1 = รอบ (a / b)! คณิตศาสตร์
Leonard Pauli

แต่ใช่ถ้าฉันจะใช้พื้นแทนด้วยเหตุผลบางอย่างคุณก็คิดถูก! ;)
Leonard Pauli

9

อีกวิธีหนึ่ง :

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

7

มีคำตอบที่ดีอยู่แล้ว อย่างไรก็ตามสำหรับสถานการณ์ที่เนื้อหาไม่พอดีกับหน้าทั้งหมด - และหากชอบฉันคุณต้องการใช้ผลลัพธ์สำหรับ a 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
}

6

เพียงแค่หารค่าชดเชยปัจจุบันด้วยขนาดหน้า:

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

11
แคสต์ไปที่ int แล้วกำหนดให้ลอย? ทำไมไม่ทำ pageNum int ด้วย;)
Klaas

4

โซลูชันของ 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 ด้วย วิธีที่ง่ายกว่ามากคือทำให้ currentPage เป็นโมฆะและตั้งค่าเฉพาะเมื่อมีการร้องขอ ... ทั้งหมดจากคลาสย่อยหรือหมวดหมู่ใน UIScrollView

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

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

getter และ Setter นี้ควรให้หน้าปัจจุบันและให้คุณเลื่อนไปยังหน้าที่ระบุ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.