UIScrollView頻道滑動(授人以魚,不如授人以漁)

        內容型APP(比如新聞,視頻),通常採用多個頁面(頻道)滑動;另外,自動滾動的焦點圖用到比較多的。本文簡單介紹使用UIScrollView實現上述功能的原理,並附部分代碼。無論是頻道的滑動,還是焦點圖自動滑動,都是基於UIScrollView的特性,viewController 實現UIScrollView的代理,並做一些控制即可。
核心思想:
    ★使用UIScrollerview作爲承載view。各個頻道添加到UIScrollerview上。注意:UIScrollerview需要提前知道頻道數量,進而確定UIScrollerview的frame.width
    ★當滑動屏幕一半兒的時候,調用UIScrollView 的- (void)scrollRectToVisible:(CGRect) animated:(BOOL)方法,實現整頁滾動。
    ★當滑動屏幕不到一半兒的時候,由於啓用了UIScrollView的pagingEnabled屬性,所以,UIScrollView會自動彈回原位置。

關鍵代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];   /*創建scrollerview*/
    self.scrollView.pagingEnabled = YES; /*scroller 一頁頁滑動,而不是一直滑下去*/
    self.scrollView.scrollsToTop = NO;       /*點擊狀態欄,是否滾到頂部。不*/
    self.scrollView.bounces = YES;           /*到達邊界回彈*/
    self.scrollView.alwaysBounceHorizontal = YES;   /*如果水平方向,內容寬度小於bound,仍可以滑動回彈*/
    self.scrollView.alwaysBounceVertical = NO;         /*如果垂直方向,內容高度小於bound,不讓滑動回彈*/
    self.scrollView.showsHorizontalScrollIndicator = NO;/*橫向滾動條,不顯示*/
    self.scrollView.showsVerticalScrollIndicator = NO;    /*縱向滾動條,不顯示*/
    
    /*添加到viewController中的view之上*/
    [self.view addSubview:self.scrollView];
}
========================================================================
//內存警告的時候,卸載多餘的page。保留current前後兩個page
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    
    for (NSInteger i = 0; i < [self.viewControllers count]; i++) {
        if (i < self.currentPage - 1 || i > self.currentPage + 1) {
            [self unloadViewControllerByPage:i];
        }
    }
}
========================================================================
- (void)willScrollToPage:(NSInteger)page animated:(BOOL)animated {
    //在滑動到page時候,處理邏輯。子類可重寫該方法
}


- (void)didScrollToPage:(NSInteger)page animated:(BOOL)animated {
    //在滑動到page時候,處理邏輯。子類可重寫該方法
    [self scrollToPage:index animated:YES];
}

========================================================================

//跳轉任意頻道。
- (void)scrollToPage:(NSInteger)page animated:(BOOL)animated {
    NSInteger lastPage = self.currentPage;
    [self setCurrentPage:page animated:animated];
    if (self.currentPage != lastPage) {
        [self removeViewControllerByPage:lastPage];
    }
    
        CGRect bounds = UIEdgeInsetsInsetRect(self.scrollView.bounds, self.scrollView.contentInset);
        bounds.origin.x = CGRectGetWidth(bounds) * page;
        bounds.origin.y = 0;
    /* animated參數,一定要NO,不然滑動時候產生抖動 */
    [self.scrollView scrollRectToVisible:bounds animated:NO];
}

========================================================================
#pragma mark - UIScrollViewDelegate

/*手指開始拖拽*/
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    if (scrollView != self.scrollView) {
        return;
    }

    //加載後一個,前一個page
    [self addViewControllerByPage:self.currentPage - 1];
    [self addViewControllerByPage:self.currentPage + 1];
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
    if (scrollView != self.scrollView) {
        return;
    }

    //加載後一個,前一個page
    [self addViewControllerByPage:self.currentPage - 1];
    [self addViewControllerByPage:self.currentPage + 1];
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if (scrollView != self.scrollView) {
        return;
    }
    
    if (decelerate) {
        return;
    }
    
    CGFloat width = CGRectGetWidth(scrollView.bounds);
    CGFloat position = self.scrollView.contentOffset.x;
    [self setCurrentPage:round(position / width) animated:YES];
    
    if (!decelerate) {
        for (NSInteger i = 0; i < self.numberOfPages; i++) {
            if (i != self.currentPage) {
                [self removeViewControllerByPage:i];
            }
        }
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    if (scrollView != self.scrollView) {
        return;
    }
    
    CGFloat width = CGRectGetWidth(scrollView.bounds);
    CGFloat position = self.scrollView.contentOffset.x;
    [self setCurrentPage:round(position / width) animated:YES];
    
    for (NSInteger i = 0; i < self.numberOfPages; i++) {
        if (i != self.currentPage) {
	    //非移除currentPage
            [self removeViewControllerByPage:i];
        }
    }
}


發佈了184 篇原創文章 · 獲贊 450 · 訪問量 184萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章