UIScrollView的基礎(chǔ)
UIScrollView是一些UIKit類的父類,如UITableView、UITextView。
UIScrollView可以看作兩層-scrollView(滾動視圖,用于滾動)和contentView(內(nèi)容視圖,用于展示內(nèi)容)。
一個UIScrollView對象的核心概念是在內(nèi)容視圖上的原點上是可調(diào)整的。
UIScrollView對象以自身尺寸來剪裁內(nèi)容,但它自身尺寸通常(但不必定)與App的主窗口重合。
ScrollView跟蹤手指的移動并且相應(yīng)的調(diào)整原點。
通過ScrollView顯示內(nèi)容的View,根據(jù)固定在內(nèi)容視圖中的偏移量的新原點繪制自身的部分(ScrollView自身不參與繪制,除非顯示垂直或水平的滑動指示器)
ScrollView必須知道內(nèi)容的尺寸,以此來判斷什么時候停止?jié)L動。
默認情況下,當滾動內(nèi)容超出范圍,它會有反彈效果。
管理ScrollView中繪制內(nèi)容顯示的對象,應(yīng)平鋪內(nèi)容的子視圖,以至于沒有View超出屏幕大小。
當用戶在滾動視圖中滾動時,此對象應(yīng)根據(jù)要求添加或刪除子視圖。
觸摸事件分發(fā)原理
因為ScrollView沒有ScrollBar,他必須知道一個觸摸操作是否代表一個滾動意圖還是一個跟蹤內(nèi)容中的子View的意圖。
為了判斷,它通過啟動一個計時器暫時攔截觸摸事件,并在計時器觸發(fā)之前,查看觸摸是否有移動。
若計時器在沒有位置變化的情況下觸發(fā),則ScrollView將跟蹤事件傳遞給內(nèi)容中的子View。
若用戶在計時器停止前將手指拖到了足夠遠的距離,則ScrollView會取消內(nèi)容中子View的跟蹤事件,并執(zhí)行滾動操作。
子類可以重寫touchesShouldBegin()、isPagingEnabled()和touchesShouldCancel()方法(由scrollView調(diào)用),來影響scrollView處理滾動手勢的方式。
若你給View的restorationIdentifier屬性設(shè)置了值,它會嘗試在app崩潰時保留滾動相關(guān)的信息,特殊的,將保留zoomScale,contentInset和contentOffset屬性的值。
在重啟時,ScrollView保存的值,使內(nèi)容顯示滾動到以前相同位置。
UIScrollView的主要屬性
| 屬性 | 含義 |
|---|---|
| frame | 滾動視圖(可見區(qū)域)的大小和位置 |
| contentSize | 代表內(nèi)容視圖的大小 |
| indicatorStyle | 滑動光標的樣式 |
| bounces | 滑動到邊緣時具有反彈效果 |
| isPagingEnabled | 分頁效果,每次移動一個格 |
| contentOffset | UIScrollView當前顯示區(qū)域的頂點相對于UIScrollView的frame的坐標。 |
| bouncesZoom | 類似于bounces屬性,這個屬性可以讓用戶的縮放操作超出最大或最小縮放級別,然后彈回。 |
| minimumZoomScale | 最小縮放比例 |
| maximumZoomScale | 最大縮放比例 |
| showsHorizontalScrollIndicator | 顯示水平滾動條 |
| showsVerticalScrollIndicator | 顯?垂直滾動條 |
| scrollsToTop | 點擊狀態(tài)欄返回頂部 |
在UIScrollView中添加控件
func configViews() {
let scrollView = UIScrollView.init(frame: CGRect.init(x: 0, y: 0, width: 414, height: 200))
scrollView.contentSize = CGSize.init(width: 414 * 5, height: 200)
scrollView.backgroundColor = .gray
scrollView.indicatorStyle = .white
scrollView.bounces = true
view.addSubview(scrollView)
let label = UILabel.init(frame: CGRect.init(x: 414, y: 0, width: 414, height: 50))
label.textColor = .red
label.text = "hello"
scrollView.addSubview(label)
}
委托代理方法
拓展含有UIScrollView的ViewController繼承UIScrollViewDelegate,其中的一些常用的方法
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// 滾動時不停的回調(diào)
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
// 縮放過程中持續(xù)觸發(fā)
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
// 用戶首次拖動時調(diào)用
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
// 將要結(jié)束拖動時調(diào)用
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
// 用戶手指停止拖動,離開屏幕時調(diào)用
}
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
// 將要開始減速時調(diào)用
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// 減速完成時觸發(fā),速度為0,通常在這里獲取scrollView的contentOffset
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
// 給scrollView設(shè)置一個結(jié)束動畫的時候觸發(fā),不指定動畫不會觸發(fā)
}
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
// 將要開始縮放時觸發(fā)
}
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
// 結(jié)束縮放時觸發(fā)
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
// 設(shè)置點擊狀態(tài)欄時是否會到頂部
return true
}
func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
// scrollView已返回頂部時觸發(fā)
}
}