UIScrollView 的相關滑動代理回調方法及屬性在滑動時的變化

如題, 雖然用了不少不少次 UIScrollView, 知道它有一些滑動代理回調方法, 知道它有一些滑動狀態相關的屬性, 但對這些方法在每個時間點的具體狀態老是不太肯定, 看官方說明文檔也是一頭霧水. 索性此次將全部的代理方法及屬性調用一遍, 而後記錄下結果.swift

對於這種涉及到狀態變化的描述, 文字彷佛有些蒼白無力, 因而我嘗試用圖表的方式來進行記錄, 以期更加直觀.markdown

情景一: 拖拽加速而後鬆開自由滑動

himg

若是滑動到底部, 且 ScrollViewbounces 回彈效果的話, 那麼最後一次的 scrollViewDidScrollisDraging 屬性爲 falseide

情景二: 緩慢拖拽而後鬆開

himg

總結

  • isDraging: 表示 scrollView 是否在自由滑動或者當前手指在接觸屏幕oop

    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: 表示當前手指是否與屏幕接觸測試

    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: 這個簡單的多, 就是表示是否正在減速, 也就是說只有當慣性滑動的時候纔會爲 trueui

    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

爲了便於讀者獨立測試驗證, 這裏附上完整代碼this

//
// 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
    }
}
複製代碼
相關文章
相關標籤/搜索