IOS學習筆記——iOS元件之UIScrollView詳解

真煩人發表於2014-12-08

引言

UIScrollView的是幾個UIKit類包括的UITableView和UITextView中的超類。

一個UIScrollView物件(或者,簡單地說,一個滾動檢視)的核心概念是,它是一個檢視,其起源是可調過的內容檢視。它剪輯的內容,它的框架,這通常(但不一定)恰逢該應用程式的主視窗。滾動檢視跟蹤手指的變動,並相應調整原點。這正顯示出它的內容“,通過”滾動檢視的檢視繪製的基礎上,新的原點,它被固定在內容檢視的偏移部分本身。滾動檢視本身沒有繪製,除了顯示垂直和水平滾動的指標。滾動檢視必須知道的內容檢視的大小,所以它知道何時停止滾動,預設情況下,它“反彈”回來時,滾動超出了內容的範圍。

用於管理內容的繪製有關的物件顯示在一個滾動檢視應該瓦片的內容的子檢視,以便沒有檢視超過螢幕的大小。當使用者在滾動滾動檢視,這個物件應該新增和刪除子檢視是必要的。

由於滾動檢視沒有滾動條,它必須知道是否觸控訊號的意圖與滾動意圖在內容跟蹤一個子檢視。做出此決定,它暫時攔截觸控按下事件通過啟動一個定時器,並在定時器觸發之前,看是否觸控手指做任何運動。如果定時器觸發無位置顯著的變化,滾動檢視將跟蹤事件的內容檢視的感動子檢視。然後,如果使用者在定時器期滿前拉著自己的手指遠遠不夠,滾動檢視將取消任何跟蹤的子檢視,並進行滾動本身。子類可以重寫touchesShouldBegin : withEvent:方法inContentView :,pagingEnabled和touchesShouldCancelInContentView :方法(這是由滾動檢視呼叫)來影響滾動檢視如何處理滾動手勢。

滾動檢視還處理縮放和平移的內容。當使用者使一個夾在或向外擠壓手勢,滾動檢視調整偏移量和內容的標度。當手勢結束,管理內容檢視中的物件應該要更新的內容為必要的子檢視。 (請注意,手勢可以結束和手指仍可能下跌。 )雖然手勢正在進行中,滾動檢視不傳送任何跟蹤呼叫子檢視。

該UIScrollView的類可以有必須採取UIScrollViewDelegate協議的委託。對於縮放和平移工作,委託必須實現viewForZoomingInScrollView :和scrollViewDidEndZooming : withView : atScale : ,此外,最大( maximumZoomScale )和最小( minimumZoomScale )變焦倍數必須是不同的。

方法&&屬性:

// 監控目前滾動的位置(預設CGPointZero)

cCGPoint                      contentOffset; 
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;

// 滾動範圍的大小(預設CGSizeZero)

cCGSize                       contentSize; 

// 檢視在scrollView中的位置(UIEdgeInsetsZero)

cUIEdgeInsets                 contentInset;   

// 設定協議

cid<UIScrollViewDelegate>      delegate;

// 指定控制元件是否只能在一個方向上滾動(預設為NO)

cBOOL directionalLockEnabled; 

// 控制控制元件遇到邊框是否反彈(預設為YES)

cBOOL                         bounces; 

// 控制垂直方向遇到邊框是否反彈(預設為NO,如果為YES,bounces也是YES)

cBOOL                         alwaysBounceVertical;  

// 控制水平方向遇到邊框是否反彈(預設為NO,如果為YES,bounces也是YES)

cBOOL                         alwaysBounceHorizontal;

// 控制控制元件是否整頁翻動(預設為NO)

cBOOL          pagingEnabled; 

// 控制控制元件是否能滾動

cBOOL          scrollEnabled;

// 控制是否顯示水平方向的滾動條

cBOOL                         showsHorizontalScrollIndicator; 

// 控制是否顯示垂直方向的滾動條

cBOOL                         showsVerticalScrollIndicator;

// 指定滾動條在scrollerView中的位置

cUIEdgeInsets                 scrollIndicatorInsets; 

// 設定滾動條的樣式

cUIScrollViewIndicatorStyle   indicatorStyle;  

UIScrollViewDelegate詳解

c//scrollView滾動時,就呼叫該方法。任何offset值改變都呼叫該方法。即滾動過程中,呼叫多次 
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidScroll");
    CGPoint point=scrollView.contentOffset;
    NSLog(@"%f,%f",point.x,point.y);
    // 從中可以讀取contentOffset屬性以確定其滾動到的位置。

    // 注意:當ContentSize屬性小於Frame時,將不會出發滾動


}
c// 當scrollView縮放時,呼叫該方法。在縮放過程中,回多次呼叫
- (void)scrollViewDidZoom:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidScroll");
    float value=scrollView.zoomScale;
    NSLog(@"%f",value);


}
c// 當開始滾動檢視時,執行該方法。一次有效滑動(開始滑動,滑動一小段距離,只要手指不鬆開,只算一次滑動),只執行一次。
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

    NSLog(@"scrollViewWillBeginDragging");

}
c// 滑動scrollView,並且手指離開時執行。一次有效滑動,只執行一次。
// 當pagingEnabled屬性為YES時,不呼叫,該方法
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{

    NSLog(@"scrollViewWillEndDragging");

}
c// 滑動檢視,當手指離開螢幕那一霎那,呼叫該方法。一次有效滑動,只執行一次。
// decelerate,指代,當我們手指離開那一瞬後,檢視是否還將繼續向前滾動(一段距離),經過測試,decelerate=YES
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

    NSLog(@"scrollViewDidEndDragging");
    if (decelerate) {
        NSLog(@"decelerate");
    }else{
         NSLog(@"no decelerate");

    }

    CGPoint point=scrollView.contentOffset;
    NSLog(@"%f,%f",point.x,point.y);

}
c// 滑動減速時呼叫該方法。
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{

    NSLog(@"scrollViewWillBeginDecelerating");
    // 該方法在scrollViewDidEndDragging方法之後。


}
c// 滾動檢視減速完成,滾動將停止時,呼叫該方法。一次有效滑動,只執行一次。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidEndDecelerating");

    [_scrollView setContentOffset:CGPointMake(0, 500) animated:YES];

}
c// 當滾動檢視動畫完成後,呼叫該方法,如果沒有動畫,那麼該方法將不被呼叫
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidEndScrollingAnimation");
    // 有效的動畫方法為:
    //    - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated 方法
    //    - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated 方法


}
c// 返回將要縮放的UIView物件。要執行多次
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{

    NSLog(@"viewForZoomingInScrollView");
    return  self.imgView;

}
c// 當將要開始縮放時,執行該方法。一次有效縮放,就只執行一次。
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view{

    NSLog(@"scrollViewWillBeginZooming");

}
c// 當縮放結束後,並且縮放大小回到minimumZoomScale與maximumZoomScale之間後(我們也許會超出縮放範圍),呼叫該方法。
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{

    NSLog(@"scrollViewDidEndZooming");

}
c// 指示當使用者點選狀態列後,滾動檢視是否能夠滾動到頂部。需要設定滾動檢視的屬性:_scrollView.scrollsToTop=YES;
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView{

    return YES;


}
c// 當滾動檢視滾動到最頂端後,執行該方法
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidScrollToTop");
}

Tip:判斷uiscrollview是向上滾動還是向下滾動

cint _lastPosition;    //A variable define in headfile  

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{  
    int currentPostion = scrollView.contentOffset.y;  
    if (currentPostion - _lastPosition > 25) {  
        _lastPosition = currentPostion;  
        NSLog(@"ScrollUp now");  
    }  
    else if (_lastPosition - currentPostion > 25)  
    {  
        _lastPosition = currentPostion;  
        NSLog(@"ScrollDown now");  
    }  
}
// 25 可以是任意數字,可根據自己的需要來設定。
c// 升級版:到達頂部或底部時不會反彈
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    int currentPostion = scrollView.contentOffset.y;

    if (currentPostion - _lastPosition > 20  && currentPostion > 0) {        //這個地方加上 currentPostion > 0 即可)
        _lastPosition = currentPostion;

        NSLog(@"ScrollUp now");
    }
    else if ((_lastPosition - currentPostion > 20) && (currentPostion  <= scrollView.contentSize.height-scrollView.bounds.size.height-20) ){
        _lastPosition = currentPostion;

        NSLog(@"ScrollDown now");
    }
}

其他

UIScrollView 實踐經驗

相關文章