1. 程式人生 > >iOS 關於Objective-C中UIScrollView的使用總結

iOS 關於Objective-C中UIScrollView的使用總結

前言:由於之前很早寫的關於【iOS 關於UIScrollView的幾點總結】,是從自己的markdown筆記直接拷貝過來後也沒有整理,所以在閱讀上顯得有點亂, 今天花時間重新整理排版了下,方便閱讀。還請見諒這麼久才重新整理。

1、什麼是 UIScrollView ?
  • 當手機螢幕需要展示的內容較多超出一個螢幕時,使用者可以通過滾動手勢來檢視螢幕以外的內容。
  • 普通的 UIView 不具備滾動的功能,UIScrollView 是一個能夠滾動的檢視控制元件,可以用來展示大量的內容,並且可以通過滾動檢視所有的內容。
2、UIScrollView 的常見屬性
  • UIScrollView
    滾動的位置
  • 內容左上角與 ScrollView 左上角的間距值
@property (nonatomic) CGPoint contentOffset;

image

  • UIScrollView 內容的尺寸, 滾動範圍
@property (nonatomic) CGSize contentSize;
  • UIScrollView 的4周增加額外的滾動區域,一般用來避免 ScrollView 的內容被其它控制元件擋住
@property (nonatomic) UIEdgeInsets contentInset;
3、UIScrollView 各尺寸

image

4、UIScrollView
的其他屬性
  • 回彈效果
@property (nonatomic) BOOL bounces;

// 取消回彈效果
self.scrollView.bounces = NO;
  • 是否能滾動
@property (nonatomic, getter = isScrollEnabled) BOOL scrollEnabled;
  • 是否顯示水平滾動條
@property (nonatomic) BOOL showsHorizontalScrollIndicator;
  • 是否顯示垂直滾動條
@property (nonatomic) BOOL showsVerticalScrollIndicator;
5、 UIScrollView 的基本使用
  • 設定 UIScrollView的contentSize 屬性,告訴 UIScrollView 所有內容的尺寸,也就是告訴它滾動的範圍
  • UIScrollView 使用步驟

    • 建立 UIScrollView;
    • 將需要展示的內容新增到 UIScrollView 中;
    • 設定 UIScrollView 的滾動範圍(contentSize)。
  • 注意:如果想讓 UIScrollView 進行滾動,必須設定可以滾動的範圍,必須設定可以滾動的範圍

  • 一個控制元件沒有設定 frame ,預設 x/y 都是 0

6、ScrollView 不能滾動的幾種情況
  • 沒有設定 contentSize

    • scrollEnabled 屬性 = NO ; // 代表控制元件不可用

    • userInteractionEnabled 屬性 = NO; // 代表控制元件不能和使用者互動

image

7、如何去掉滾動條
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
  • 注意:滾動條也是 scrollValue 的子控制元件的一部分

    • 滾動條可能在子控制元件的前面,也可能在子控制元件的後面
  • 正是因為這個原因,在開發中不推薦使用 subviews 獲取子控制元件的方式

  • 當沒有設定 contentSize 情況下,滾動條在其它子控制元件的前面列印,當設定了contentSize 情況下,滾動條在其它子控制元件後面列印,這說明了滾動條的位置是不確定的。

image

  • 設定滾動條的樣式
// default is UIScrollViewIndicatorStyleDefault
@property (nonatomic) UIScrollViewIndicatorStyle  indicatorStyle;                
  • 預設情況下UIScrollView有一個回彈效果
    • 只要設定了contentSize就有回彈效果
// 回彈效果
// default YES. if YES, bounces past edge of content and back again
@property (nonatomic) BOOL bounces;                        
  • 預設如果不設定 contentSize,scrollView是沒有回彈效果的,可是如果設定了self.scrollView.alwaysbounceVertical = YES & self.scrollView.alwaysBounceHorizontal = YES的情況下,水平和垂直方向就都有了回彈效果

    • 一般應用於下拉重新整理功能

image

  • 設定邊距

  • contentInset(額外增加的邊距)


@property(nonatomic)        UIEdgeInsets                contentInset;                  // default UIEdgeInsetsZero. add additional scroll area around content
  • 設定內容偏移位

    • contentOffset (移動的位置是一個臨時的位置,只要輕輕拖拽一下就會回到預設的位置)
  • 計算公式:永遠都是 控制元件的左上角 - 內容的左上角 = 規定的值

 // animate at constant velocity to new offset
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated; 
8、UIScrollView代理
  1. 如何監聽一個控制元件的變化/狀態

    • 首先需要檢視該控制元件的標頭檔案,看它繼承於誰
    • 如果繼承於UIControl,那麼就可以通過addTarget來監聽
    • 如果繼承於UIView,那麼就必須通過代理來監聽
  2. 代理作用:

    • A 物件想監聽 B 物件的變化,那麼可以讓 A 成為 B 的代理
    • B 物件發生一些變化想通知 A物件,那麼可以讓 A 成為 B 的代理
    • self 寫在物件方法中就是當前物件的例項物件
  3. 代理協議的規律:

    • 定義代理都使用 id ,這樣以後就任意物件都能成為代理(學官方)
    • 以控制元件的類名開頭,後面加上 delegate
    • 代理協議可以寫在 interface() 後面,也可以寫在類擴充套件後面,都是可以的
  4. 代理協議中的方法名的規律:

    • 一般以控制元件名稱去掉類字首開頭
  5. 代理協議中的方法引數的規律:

    • 誰觸發事件,就將誰傳遞進來
  6. 如何監聽 UIScrollView 的變化

    • 成為UIScrollView的代理
    • 遵守UIScrollView的協議
    • 實現UIScrollView協議中的方法
  7. 只要成為了 UIScrollView 的代理,遵守代理協議,實現協議中的方法,當UIScrollView放生一些變化的時候,系統就會自動呼叫這些代理方法

    • scrollViewDidScroll: 方法只要 UIScrollView 滾動了,系統就會自動呼叫
// 只要UIScrollView滾動就會呼叫
// 系統會自動呼叫這些方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView; // any offset changes

// 只要使用者準備開始拖拽就會呼叫
// called on start of dragging (may require some time and or distance to move)
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;

// 使用者停止拖拽(已經鬆手)
// 但是並不意味著UIScrollView已經停止滾動了,每次呼叫此方法時,系統都會傳入一個當前是否有慣性的引數(decelerate)
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

// UIScrollView停止減速
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;      // called when scroll view grinds to a halt

8.注意:

  • 如果想在 UIScrollView 停止滾動之後做一些操作,有以下兩種情況:

    • 沒有慣性:只會呼叫停止拖拽的方法,不會呼叫停止減速的方法
    • 有慣性:既會呼叫停止拖拽的方法,也會呼叫停止減速的方法
  • 所以:以後要判斷UIScrollView是否停止滾動,需要同時重寫兩個方法:

    • scrollViewDidEndDragging
    • scrollViewDidEndDecelerating
// 在開發中如果需要監聽scrollView滾動是否停止可以這樣寫
- (void)scrollViewDidEndDragging:(nonnull UISrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (decelerate == NO) {
  [self scrollViewDidEndDecelerating:scrolView];
} else {

}
}

- (void)scrollViewDidEndDecelerating:(nonnull UIScrollView *)scrollView
{
  // 在這裡面寫scrollView停止時需要做的事情
  NSLog(@"UIScrollView停止滾動了");
}

9.為什麼代理要用 weak

  • 任何物件都能成為代理,只要兩者之間遵守了代理協議即可
  • 原因:為了防止迴圈引用
  • 控制器-強引用 -> 控制器的 View-強引用 -> subViews陣列-強引用 -> UIScrollView-弱引用 -> 控制器
  • 如果只有一個控制器的情況,程式一啟動就建立的這個控制器是不會被釋放的(如果它被釋放,它所執行的邏輯肯定不能被執行 )
  • 只要陣列中儲存了物件,這個陣列就會用強指標指向了這個物件
  • strong (用於物件, 強指標, 強引用)
  • weak(用於物件, 一般應用於控制元件/代理)
  • copy(用於物件, 字串, 主要為了防止外界修改內部的屬性的值)
  • assign(用於基本資料型別,int/float/double...)

image

9、UIScrollView 縮放
  1. 要想縮放,除了告訴 UIScrollView 要縮放哪一個控制元件以外,還要告訴UIScrollView 最小能縮多小,最大能放多大
    • 因為所有的子控制元件都是我們新增進去的,所以要縮放哪一個我們最清楚
    • 只要讓控制器成為 UIScrollView 的代理,當 UIScrollView 不清楚要縮放哪一個控制元件的時候, UIScrollView 就會呼叫它的代理方法,問問代理到底要縮放哪一個
self.sc.maximumZoomScale = 2.0;
self.sc.minimumZoomScale = 0.5;

2.縮放圖片分為兩步

  • 成為代理,通過代理方法告訴 UIScrollView 要縮放哪一個子控制元件
  • 設定子控制元件和最小的縮放比

3.想要縮放,必須明確告訴 UIScrollView 要縮放哪一個控制元件,因為 UIScrollView中可能有很多子控制元件

// 代理方法
// 大部分代理方法是由控制元件名開頭,小部分不是
// 在此方法中告訴UIScrollView要縮放哪一個控制元件
- (UIView *)viewForZoomingInScrollView:(nonnull UISCrollView *)scrollView {
  return 需要縮放的圖片
}

// 縮放的過程中呼叫
- (void)scrlooViewDidZoom:(nonnull UIScrollView *)scrolView {
}

// 縮放結束時呼叫
- (void)scrollViewDidEndZooming:(nonnull UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale {
}
10、UIScrollView
  1. 一個控制元件如果沒有設定 frame ,預設 x/y就是 0
  2. 如果想讓 UIScrollView 進行滾動,必須設定可以滾動的範圍
    • 將需要展示的內容新增到 UIScrollView
    • 設定 UIScrollViewcontentSize 屬性,設定滾動範圍
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width + 100, self.scrollView.frame.size.height + 100);

3.注意:scrollView不能滾動的幾種情況

  • 沒有設定contentSize
  • scrollEnabled 屬性 = NO (代表控制元件是否可用)
  • userINteractionEnabled屬性 = NO (代表控制元件不能和使用者互動,不能響應使用者操作)
11、UIScrollView 使用步驟
  1. 建立 UIScrollView
  2. 將需要展示內容新增到 UISCrollView
  3. 設定 UISCrollView 的滾動範圍(contentSize)
12、UIScrollView 圖片輪播器
  1. pagingEnabled 實現分頁的本質,是按照 UIScrollView 的寬度或者高度來分頁的.