UIScrollView的基礎(chǔ)
UIScrollView是一些UIKit類的父類押框,如UITableView、UITextView米碰。
UIScrollView可以看作兩層-scrollView(滾動(dòng)視圖卦尊,用于滾動(dòng))和contentView(內(nèi)容視圖漫萄,用于展示內(nèi)容)。
一個(gè)UIScrollView對(duì)象的核心概念是在內(nèi)容視圖上的原點(diǎn)上是可調(diào)整的缀踪。
UIScrollView對(duì)象以自身尺寸來(lái)剪裁內(nèi)容居砖,但它自身尺寸通常(但不必定)與App的主窗口重合虹脯。
ScrollView跟蹤手指的移動(dòng)并且相應(yīng)的調(diào)整原點(diǎn)。
通過(guò)ScrollView顯示內(nèi)容的View悯蝉,根據(jù)固定在內(nèi)容視圖中的偏移量的新原點(diǎn)繪制自身的部分(ScrollView自身不參與繪制归形,除非顯示垂直或水平的滑動(dòng)指示器)
ScrollView必須知道內(nèi)容的尺寸,以此來(lái)判斷什么時(shí)候停止?jié)L動(dòng)鼻由。
默認(rèn)情況下暇榴,當(dāng)滾動(dòng)內(nèi)容超出范圍,它會(huì)有反彈效果蕉世。
管理ScrollView中繪制內(nèi)容顯示的對(duì)象蔼紧,應(yīng)平鋪內(nèi)容的子視圖,以至于沒有View超出屏幕大小狠轻。
當(dāng)用戶在滾動(dòng)視圖中滾動(dòng)時(shí)奸例,此對(duì)象應(yīng)根據(jù)要求添加或刪除子視圖。
觸摸事件分發(fā)原理
因?yàn)镾crollView沒有ScrollBar向楼,他必須知道一個(gè)觸摸操作是否代表一個(gè)滾動(dòng)意圖還是一個(gè)跟蹤內(nèi)容中的子View的意圖查吊。
為了判斷,它通過(guò)啟動(dòng)一個(gè)計(jì)時(shí)器暫時(shí)攔截觸摸事件湖蜕,并在計(jì)時(shí)器觸發(fā)之前逻卖,查看觸摸是否有移動(dòng)。
若計(jì)時(shí)器在沒有位置變化的情況下觸發(fā)昭抒,則ScrollView將跟蹤事件傳遞給內(nèi)容中的子View评也。
若用戶在計(jì)時(shí)器停止前將手指拖到了足夠遠(yuǎn)的距離,則ScrollView會(huì)取消內(nèi)容中子View的跟蹤事件灭返,并執(zhí)行滾動(dòng)操作盗迟。
子類可以重寫touchesShouldBegin()、isPagingEnabled()和touchesShouldCancel()方法(由scrollView調(diào)用)熙含,來(lái)影響scrollView處理滾動(dòng)手勢(shì)的方式罚缕。
若你給View的restorationIdentifier屬性設(shè)置了值,它會(huì)嘗試在app崩潰時(shí)保留滾動(dòng)相關(guān)的信息婆芦,特殊的怕磨,將保留zoomScale,contentInset和contentOffset屬性的值消约。
在重啟時(shí)肠鲫,ScrollView保存的值,使內(nèi)容顯示滾動(dòng)到以前相同位置或粮。
UIScrollView的主要屬性
屬性 | 含義 |
---|---|
frame | 滾動(dòng)視圖(可見區(qū)域)的大小和位置 |
contentSize | 代表內(nèi)容視圖的大小 |
indicatorStyle | 滑動(dòng)光標(biāo)的樣式 |
bounces | 滑動(dòng)到邊緣時(shí)具有反彈效果 |
isPagingEnabled | 分頁(yè)效果导饲,每次移動(dòng)一個(gè)格 |
contentOffset | UIScrollView當(dāng)前顯示區(qū)域的頂點(diǎn)相對(duì)于UIScrollView的frame的坐標(biāo)。 |
bouncesZoom | 類似于bounces屬性,這個(gè)屬性可以讓用戶的縮放操作超出最大或最小縮放級(jí)別渣锦,然后彈回硝岗。 |
minimumZoomScale | 最小縮放比例 |
maximumZoomScale | 最大縮放比例 |
showsHorizontalScrollIndicator | 顯示水平滾動(dòng)條 |
showsVerticalScrollIndicator | 顯?垂直滾動(dòng)條 |
scrollsToTop | 點(diǎn)擊狀態(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) {
// 滾動(dòng)時(shí)不停的回調(diào)
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
// 縮放過(guò)程中持續(xù)觸發(fā)
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
// 用戶首次拖動(dòng)時(shí)調(diào)用
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
// 將要結(jié)束拖動(dòng)時(shí)調(diào)用
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
// 用戶手指停止拖動(dòng)袋毙,離開屏幕時(shí)調(diào)用
}
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
// 將要開始減速時(shí)調(diào)用
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// 減速完成時(shí)觸發(fā)型檀,速度為0,通常在這里獲取scrollView的contentOffset
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
// 給scrollView設(shè)置一個(gè)結(jié)束動(dòng)畫的時(shí)候觸發(fā)听盖,不指定動(dòng)畫不會(huì)觸發(fā)
}
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
// 將要開始縮放時(shí)觸發(fā)
}
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
// 結(jié)束縮放時(shí)觸發(fā)
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
// 設(shè)置點(diǎn)擊狀態(tài)欄時(shí)是否會(huì)到頂部
return true
}
func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
// scrollView已返回頂部時(shí)觸發(fā)
}
}