如題, 雖然用了很多很多次 UIScrollView, 知道它有一些滑動(dòng)代理回調(diào)方法, 知道它有一些滑動(dòng)狀態(tài)相關(guān)的屬性, 但對(duì)這些方法在每一個(gè)時(shí)間點(diǎn)的具體狀態(tài)總是不太確定, 看官方說(shuō)明文檔也是一頭霧水. 索性這次將所有的代理方法及屬性調(diào)用一遍, 然后記錄下結(jié)果.
對(duì)于這種涉及到狀態(tài)變化的描述, 文字似乎有些蒼白無(wú)力, 于是我嘗試用圖表的方式來(lái)進(jìn)行記錄, 以期更加直觀.
情景一: 拖拽加速然后松開(kāi)自由滑動(dòng)
如果滑動(dòng)到底部, 且
ScrollView
有bounces
回彈效果的話, 那么最后一次的scrollViewDidScroll
的isDraging
屬性為false
情景二: 緩慢拖拽然后松開(kāi)
總結(jié)
-
isDraging
: 表示scrollView
是否在自由滑動(dòng)或者當(dāng)前手指在接觸屏幕A Boolean value that indicates whether the user has begun scrolling the content. The value held by this property might require some time or distance of scrolling before it is set to true.
-
isTracking
: 表示當(dāng)前手指是否與屏幕接觸Returns whether the user has touched the content to initiate scrolling. The value of this property is true if the user has touched the content view but might not have yet have started dragging it.
-
isDecelerating
: 這個(gè)簡(jiǎn)單的多, 就是表示是否正在減速, 也就是說(shuō)只有當(dāng)慣性滑動(dòng)的時(shí)候才會(huì)為true
Returns whether the content is moving in the scroll view after the user lifted their finger. The returned value is true if user isn't dragging the content but scrolling is still occurring.
Code
為了便于讀者獨(dú)立測(cè)試驗(yàn)證, 這里附上完整代碼
//
// TableViewVC.swift
// HLTest
//
// Created by Hanley Lee on 2021/5/19.
// Copyright ? 2021 Hanley Lee. All rights reserved.
//
import UIKit
class TableViewVC: UITableViewController {
var startTime: CFTimeInterval = .init()
var des: String {
return "isDragging: \(tableView.isDragging), isTracking: \(tableView.isTracking), isDecelerating: \(tableView.isDecelerating), interval: \(CACurrentMediaTime() - startTime)"
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = 50
tableView.register(TableViewCell.self, forCellReuseIdentifier: "TableViewCell")
startTime = CACurrentMediaTime()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { _ in
print(self.des)
}
RunLoop.current.add(timer, forMode: .common)
}
}
// MARK: - Scroll Delegate
extension TableViewVC {
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrollViewDidScroll: \(des)")
}
override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("scrollViewWillBeginDragging: \(des)")
}
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
print("scrollViewWillEndDragging: \(des)")
}
override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
print("scrollViewDidEndDragging: \(des)")
}
override func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
print("scrollViewWillBeginDecelerating: \(des)")
}
override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("scrollViewDidEndDecelerating: \(des)")
}
}
// MARK: - TableView Delegate & Data Source
extension TableViewVC {
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = (tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as? TableViewCell) ?? .init(frame: .zero)
cell.setContent(with: indexPath.row.description)
return cell
}
}