- 什么是UISCrollView
+ 當手機屏幕需要展示的內容較多超出一個屏幕時,用戶可以通過滾動手勢來查看屏幕以外的內容
+ 普通的UIView不具備滾動的功能,UIScrollView是一個能夠滾動的視圖控件,可以用來展示大量的內容,并且可以通過滾動查看所有的內容
---
#### UIScrollView的常見屬性
- UIScrollView滾動的位置
+ 內容左上角與scrollView左上角的間距值
```objc
@property (nonatomic) CGPoint contentOffset;
```
- UIScrollView內容的尺寸,滾動范圍
```objc
@property (nonatomic) CGSize contentSize;
```
- 在UIScrollView的4周增加額外的滾動區(qū)域,一般用來避免scrollView的內容被其它控件擋住
```objc
@property (nonatomic) UIEdgeInsets contentInset;
```
- UIScrollView各尺寸
---
#### UIScrollView的其他屬性
- 回彈效果
```objc
@property (nonatomic) BOOL bounces;
// 取消回彈效果
self.scrollView.bounces = NO;
```
- 是否能滾動
```objc
@property (nonatomic, getter = isScrollEnabled) BOOL scrollEnabled;
```
- 是否顯示水平滾動條
```objc
@property (nonatomic) BOOL showsHorizontalScrollIndicator;
```
- 是否顯示垂直滾動條
```objc
@property (nonatomic) BOOL showsVerticalScrollIndicator;
```
---
#### UIScrollView的基本使用
- 設置UIScrollView的contentSize屬性,告訴UIScrollView所有內容的尺寸,也就是告訴它滾動的范圍
- **`UIScrollView使用步驟`**
+ **`1.創(chuàng)建UIScrollView`-**
+ **`2.將需要展示的內容添加到UIScrollView中`**
+ **`3.設置UIScrollView的滾動范圍(contentSize)`**
- 注意:如果想讓UIScrollView進行滾動,必須設置可以滾動的范圍,必須設置可以滾動的范圍
+ 一個控件沒有設置frame,默認x/y都是0
- `scrollView不能滾動的幾種情況`
+ 沒有設置contentSize
+ scrollEnabled屬性 = NO; // 代表控件不可用
+ userInteractionEnabled屬性 = NO; // 代表控件不能和用戶交互
- 如何去掉滾動條
```objc
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
```
- `注意:滾動條也是scrollValue的子控件的一部分`
+ `滾動條可能在子控件的前面,也可能在子控件的后面`
+ 正是因為這個原因,在開發(fā)中不推薦使用subviews獲取子控件的方式
* 當沒有設置contentSize情況下,滾動條在其它子控件的前面打印,當設置了contentSize情況下,滾動條在其它子控件后面打印,`這說明了滾動條的位置是不確定的`
- 設置滾動條的樣式
```objc
@property(nonatomic)? ? ? ? UIScrollViewIndicatorStyle? indicatorStyle;? ? ? ? ? ? ? ? // default is UIScrollViewIndicatorStyleDefault
```
- 默認情況下UIScrollView有一個回彈效果
+ 只要設置了contentSize就有回彈效果
```objc
// 回彈效果
@property(nonatomic)? ? ? ? BOOL? ? ? ? ? ? ? ? ? ? ? ? bounces;? ? ? ? ? ? ? ? ? ? ? ? // default YES. if YES, bounces past edge of content and back again
```
- 默認如果不設置contentSize,scrollView是沒有回彈效果的,可是如果設置了`self.scrollView.alwaysbounceVertical = YES & self.scrollView.alwaysBounceHorizontal = YES `的情況下,水平和垂直方向就都有了回彈效果
+ 一般應用于下拉刷新功能
- 設置邊距
+ contentInset(額外增加的邊距)
```objc
@property(nonatomic)? ? ? ? UIEdgeInsets? ? ? ? ? ? ? ? contentInset;? ? ? ? ? ? ? ? ? // default UIEdgeInsetsZero. add additional scroll area around content
```
- 設置內容偏移位
+ contentOffset(移動的位置是一個臨時的位置,只要輕輕拖拽一下就會回到默認的位置)
* 計算公式:永遠都是 `控件的左上角 - 內容的左上角 = 規(guī)定的值`
```objc
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;? // animate at constant velocity to new offset
```
---
#### UIScrollView代理
- 如何監(jiān)聽一個控件的變化/狀態(tài)
+ 首先需要查看該控件的頭文件,看它繼承于誰
* `如果繼承于UIControl,那么就可以通過addTarget來監(jiān)聽`
* `如果繼承于UIView,那么就必須通過代理來監(jiān)聽`
- 代理作用:
+ 當A對象想監(jiān)聽B對象的變化,那么可以讓A成為B的代理
+ 當B對象發(fā)生一些變化想通知A對象,那么可以讓A成為B的代理
* self寫在對象方法中就是當前對象的實例對象
- 代理協議的規(guī)律:
+ 定義代理都使用id,這樣以后就任意對象都能成為代理(學官方)
+ 以控件的類名開頭,后面加上delegate
+ 代理協議可以寫在interface()后面,也可以寫在類擴展后面,都是可以的
- 代理協議中的方法名的規(guī)律:
+ 一般以控件名稱去掉類前綴開頭
- 代理協議中的方法參數的規(guī)律:
+ `誰觸發(fā)事件,就將誰傳遞進來`
- `如何監(jiān)聽UIScrollView的變化`
+ `1.成為UIScrollView的代理`
+ `2.遵守UIScrollView的協議`
+ `3.實現UIScrollView協議中的方法`
- 只要成為了UIScrollView的代理,遵守代理協議,實現協議中的方法,當UIScrollView放生一些變化的時候,系統(tǒng)就會自動調用這些代理方法
+ scrollViewDidScroll:方法只要UIScrollView滾動了,系統(tǒng)就會自動調用
```objc
// 只要UIScrollView滾動就會調用
// 系統(tǒng)會自動調用這些方法
- (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已經停止?jié)L動了,每次調用此方法時,系統(tǒng)都會傳入一個當前是否有慣性的參數(decelerate)
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
// UIScrollView停止減速
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;? ? ? // called when scroll view grinds to a halt
```
- 注意:
+ 如果想在UIScrollView停止?jié)L動之后做一些操作,有以下兩種情況:
* 沒有慣性:只會調用停止拖拽的方法,不會調用停止減速的方法
* 有慣性:既會調用停止拖拽的方法,也會調用停止減速的方法
+ 所以:以后要判斷UIScrollView是否停止?jié)L動,需要同時重寫兩個方法:
* scrollViewDidEndDragging
* scrollViewDidEndDecelerating
```objc
// 在開發(fā)中如果需要監(jiān)聽scrollView滾動是否停止可以這樣寫
- (void)scrollViewDidEndDragging:(nonnull UISrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(decelerate == NO){
[self scrollViewDidEndDecelerating:scrolView];
}else{
}
}
- (void)scrollViewDidEndDecelerating:(nonnull UIScrollView *)scrollView
{
// 在這里面寫scrollView停止時需要做的事情
NSLog(@"UIScrollView停止?jié)L動了");
}
```
- `為什么代理要用weak`
+ 任何對象都能成為代理,只要兩者之間遵守了代理協議即可
+ `原因:為了防止循環(huán)引用`
+ 控制器-強引用 -> 控制器的View-強引用 -> subViews數組-強引用 -> UIScrollView-弱引用 ->? 控制器
+ `如果只有一個控制器的情況,程序一啟動就創(chuàng)建的這個控制器是不會被釋放的`(如果它被釋放,它所執(zhí)行的邏輯肯定不能被執(zhí)行 )
+ 只要數組中保存了對象,這個數組就會用強指針指向了這個對象
* **`strong (用于對象, 強指針, 強引用)`**
* **`weak(用于對象, 一般應用于控件/代理)`**
* **`copy(用于對象, 字符串, 主要為了防止外界修改內部的屬性的值)`**
* **`assign(用于基本數據類型,int/float/double...)`**
---
#### UIScrollView縮放
- 要想縮放,除了告訴UIScrollView要縮放哪一個控件以外,還要告訴UIScrollView最小能縮多小,最大能放多大
+ 因為所有的子控件都是我們添加進去的,所以要縮放哪一個我們最清楚
+ 只要讓控制器成為UIScrollView的代理,當UIScrollView不清楚要縮放哪一個控件的時候,UIScrollView就會調用它的代理方法,問問代理到底要縮放哪一個
```objc
self.sc.maximumZoomScale = 2.0;
self.sc.minimumZoomScale = 0.5;
```
- 縮放圖片分為兩步
+ 成為代理,通過代理方法告訴UIScrollView要縮放哪一個子控件
+ 設置子控件和最小的縮放比
- 想要縮放,必須明確告訴UIScrollView要縮放哪一個控件,因為UIScrollView中可能有很多子控件
```objc
// 代理方法
// 大部分代理方法是由控件名開頭,小部分不是
// 在此方法中告訴UIScrollView要縮放哪一個控件
- (UIView *)viewForZoomingInScrollView:(nonnull UISCrollView *)scrollView{
return 需要縮放的圖片
}
// 縮放的過程中調用
- (void)scrlooViewDidZoom:(nonnull UIScrollView *)scrolView{
}
// 縮放結束時調用
- (void)scrollViewDidEndZooming:(nonnull UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale{
}
```
---
#### UIScrollView
- 一個控件如果沒有設置frame,默認x/y就是0
- 如果想讓UIScrollView進行滾動,必須設置可以滾動的范圍
+ 將需要展示的內容添加到UIScrollView中
+ 設置UIScrollView的contentSize屬性,設置滾動范圍
```objc
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width + 100, self.scrollView.frame.size.height + 100);
```
- `注意:`scrollView不能滾動的幾種情況
+ 沒有設置contentSize
+ scrollEnabled屬性 = NO? (代表控件是否可用)
+ userINteractionEnabled屬性 = NO (代表控件不能和用戶交互,不能響應用戶操作)
---
##### UIScrollView使用步驟
- 創(chuàng)建UIScrollView
- 將需要展示內容添加到UISCrollView中
- 設置UISCrollView的滾動范圍(contentSize)
#### UIScrollView圖片輪播器
- pagingEnabled實現分頁的本質,是按照UIScrollView的寬度或者高度來分頁的