SwiftUI 6.0(iOS 18.0)滾動視圖新增的滾動階段(Scroll Phase)監聽功能趣談

在這里插入圖片描述

何曾幾時,在 SwiftUI 開發中的禿頭小碼農們迫切需要一種能夠讀取當前滾動狀態的方法。

在這里插入圖片描述

在過去,他們往往需要借助于 UIKit 的神秘力量。不過這一切在 SwiftUI 6.0 中已成“滄海桑田”。

在本篇博文中,您將學到如下內容:

  • 1. ScrollView 滾動階段簡介
  • 2. 普度眾生的 SwiftUI 6.0
  • 3. 滾動階段更改上下文(ScrollPhaseChangeContext)
  • 4. 如何監聽列表(List)的滾動階段
  • 總結

相信學完本課后,小伙伴們在需要監聽滾動視圖滾動階段的應用場景中定能得心應手、游刃有余!

那還等什么呢?讓我們馬上開始吧!Let‘s go!!!😃


1. ScrollView 滾動階段簡介

所謂滾動階段(Scroll Phase)是指滾動視圖在滾動前、滾動中以及滾動后所處的不同階段。

早在 macOS 10.9+ 的 CoreGraphics 中就有滾動階段的概念了:

在這里插入圖片描述
在這里插入圖片描述

如果我們能及時的讀取各個滾動階段的值,我們就可以根據它們為滾動視圖提供更加“銀杏化”的定制和更流暢滾動附加體驗。

在 SwiftUI 6.0 之前,我們無法使用行之有效的方法來讀取滾動視圖當前所處的滾動階段,只有委身救助于 UIKit 的秉軸持鈞。

然而,這一切在 SwiftUI 6.0 中有了翻天覆地的變化!

2. 普度眾生的 SwiftUI 6.0

自從 SwiftUI 6.0(iOS 18.0)開始,“頓悟”的蘋果終于提供滾動階段的監聽功能了。

一方面,我們有了描述滾動階段的新類型 ScrollPhase:

在這里插入圖片描述

它包含 5 個枚舉值分別對應于 5 種滾動階段:

@frozen public enum ScrollPhase : Equatable {case idlecase trackingcase interactingcase deceleratingcase animatingpublic var isScrolling: Bool { get }
}

這些滾動階段的含義如下所示:

  • Idle - 表示當前滾動視圖處于空閑狀態,可以認為“嘛事沒有”;
  • Tracking - 表示當前用戶正輕觸滾動視圖但并沒有開始滾動;
  • Interacting - 表示用戶正在開始或繼續滾動著視圖的內容;
  • Decelerating -表示用戶已結束滾動操作,滾動視圖的滾動正在減速直至靜止狀態;
  • Animating - 表示滾動視圖被 ScrollPosition 或 ScrollViewReader 類型通過代碼動態滾動到了指定的位置;

另一方面,我們有了新的視圖改器方法 onScrollPhaseChange 專注于滾動階段的監聽:

在這里插入圖片描述

有了以上兩者的珠聯璧合,現在我們在 SwiftUI 6.0 即可輕而易舉的監聽任何滾動視圖的滾動階段啦:

struct ContentView: View {var body: some View {ScrollView {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()Divider()}}.onScrollPhaseChange { old, new inguard old != new else { return }print("new phase: \(new)")}}
}

在 Xcode 16beta 中運行效果如下所示:

在這里插入圖片描述

ScrollPhase 類型還提供一個 isScrolling 計算屬性,我們可以用它來判斷當前是否正在滾動。比如,假若視圖正在被滾動我們就“遮擋”它的顯示內容:

struct ContentView: View {@State var isScrolling = falsevar body: some View {ScrollView {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()Divider()}.redacted(reason: isScrolling ? .placeholder : [])}.onScrollPhaseChange { old, new inguard old != new else { return }print("正在滾動?\(new.isScrolling)")isScrolling = new.isScrolling}}
}

執行效果如下圖所示:

在這里插入圖片描述

3. 滾動階段更改上下文(ScrollPhaseChangeContext)

除此之外,SwiftUI 6.0 中新增的 onScrollPhaseChange 修改器還提供另一種重載(Overloading)形式,在該重載方法的閉包中我們會得到一個 ScrollPhaseChangeContext 上下文對象,使用它我們可以更多的掌控滾動的其它全局信息:

在這里插入圖片描述

nonisolated
func onScrollPhaseChange(_ action: @escaping (ScrollPhase, ScrollPhase, ScrollPhaseChangeContext) -> Void) -> some View

演示代碼如下所示,可以看到在其中我們使用 ScrollPhaseChangeContext 上下文對象打印出了更多的與滾動相關的信息:

struct ContentView: View {        var body: some View {ScrollView {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()Divider()}        }.onScrollPhaseChange { old, new, context inguard old != new else { return }print("\(new)\n\(context)")            }}
}

運行結果如下所示:

在這里插入圖片描述

ScrollPhaseChangeContext(geometry: <ScrollGeometry: contentOffset (0.0, 1694.3333333333333), contentSize (393.0, 4092.0), contentInsets <top: 59.0, leading: 0.0, bottom: 34.0, trailing: 0.0>, containerSize (393.0, 759.0), visibleRect (0.0, 1694.3333333333333, 393.0, 852.0)>, velocity: Optional((0.0, 0.0)))

4. 如何監聽列表(List)的滾動階段

雖然 SwiftUI 6.0 破繭而出的“大殺器” onScrollPhaseChange 對于我們監聽滾動狀態大有裨益,不過目前它只能應用在 ScrollView 視圖的外層。這意味著,如果將其放在 List 上將會“徒勞無功”:

struct ContentView: View {        var body: some View {List {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()}        }.onScrollPhaseChange { old, new, context inguard old != new else { return }print("\(new)\n\(context)")}}
}

上述代碼附著在 List 之上的 onScrollPhaseChange 修改器回調閉包將會無所事事,直接淪為“不舞之鶴”。

誠然我們可以使用 ScrollView 來平替 List,不過如果能在 List 上直接監聽滾動階段豈不更妙?

在 iOS 18.0beta 中,我們可以通過將 List 包裹在 Form 容器中暫時繞開此問題:

struct ContentView: View {        var body: some View {Form {List {ForEach(1...50, id: \.self) { i inText("Item \(i)").font(.title).padding()}}}.onScrollPhaseChange { old, new, context inguard old != new else { return }print("\(new)\n\(context)")}}
}

運行代碼可以看到,我們用 onScrollPhaseChange 修改器成功的捕獲到了 List 中滾動階段的改變以及其它滾動信息:

在這里插入圖片描述

我不確定這一情況在 iOS 18.0 正式版中是否能夠修復,讓我們拭目以待吧!

總結

在本篇博文中,我們介紹了 SwiftUI 6.0(iOS 18.0)滾動視圖最新的滾動階段(Scroll Phase)監聽功能,并討論了如何在原本不支持該功能的列表(List)上使用它。

感謝觀賞,再會啦!😎

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/41740.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/41740.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/41740.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一份適合新手的軟件測試練習項目

最近&#xff0c;不少讀者托我找一個能實際練手的測試項目。開始&#xff0c;我覺得這是很簡單的一件事&#xff0c;但當我付諸行動時&#xff0c;卻發現&#xff0c;要找到一個對新手友好的練手項目&#xff0c;著實困難。 我翻了不下一百個web網頁&#xff0c;包括之前推薦練…

nginx的知識面試易考點

Nginx概念 Nginx 是一個高性能的 HTTP 和反向代理服務。其特點是占有內存少&#xff0c;并發能力強&#xff0c;事實上nginx的并發能力在同類型的網頁服務器中表現較好。 Nginx 專為性能優化而開發&#xff0c;性能是其最重要的考量指標&#xff0c;實現上非常注重效率&#…

C#用鏈表和數組分別實現堆棧

1.鏈表 實現棧的四個基本功能 入棧 出棧 長度 棧頂值 public class 基礎 : MonoBehaviour {public class MyStack{//定義每一個元素的數據結構 //下一個元素 和 該元素的值public class StackData{public StackData next;public object data;public StackData(StackData next,…

linux驅動編程 - kfifo先進先出隊列

簡介&#xff1a; kfifo是Linux Kernel里面的一個 FIFO&#xff08;先進先出&#xff09;數據結構&#xff0c;它采用環形循環隊列的數據結構來實現&#xff0c;提供一個無邊界的字節流服務&#xff0c;并且使用并行無鎖編程技術&#xff0c;即當它用于只有一個入隊線程和一個出…

nginx修改網站默認根目錄及發布(linux、centos、ubuntu)openEuler軟件源repo站點

目錄 安裝nginx配置nginx其它權限配置 安裝nginx dnf install -y nginx配置nginx whereis nginxcd /etc/nginx llcd conf.d touch vhost.conf vim vhost.conf 命令模式下輸入:set nu或:set number可以顯示行號 復制如下內容&#xff1a; server {listen 80;server_name…

【0294】Postgres內核 dynahash 之 hash_search 實現原理

相關文章: 【0289】Postgres內核之哈希表(Hash Tables) 【0290】Postgres內核之dynahash(動態哈希表,dynamic hash tables)(概念篇) 【0291】Postgres內核之dynahash table 創建 【0292】Postgres內核源碼之dynahash 插入entry實現 【0293】Postgres內核之創建 dynahas…

ESP32 通過藍牙顯示歌詞代碼示例

通過藍牙協議播放音樂&#xff0c;有的時候需要顯示歌詞&#xff0c;這里就是a2dp庫獲取了歌詞 值得注意的是要想正確獲取到歌詞&#xff0c;必須打開各種播放器的字幕&#xff08;歌詞&#xff09;開關 本項目用了三個開源庫 a2dp&#xff0c;tft_espi,xfont. a2dp &#x…

基于python實現的監聽服務接口是否正常,發送異常消息到釘釘群

獲取釘釘機器人 創建釘釘群組(要求至少三個成員)進入群組 設置>機器人>添加機器人選擇自定義機器人 按照要求填寫完獲取到 Webhook的鏈接 實現代碼 from time import sleep import requests import json from datetime import datetime import logging# 配置日志記錄的…

數據結構第11節: B樹

B樹是一種自平衡的樹數據結構&#xff0c;它能夠保持數據排序&#xff0c;并且在插入、刪除和查找操作中具有對數時間復雜度。B樹廣泛應用于文件系統、數據庫和索引中&#xff0c;因為它們可以有效地處理大量數據。 B樹的特點&#xff1a; 所有葉子節點都位于同一層。每個節點…

【】AI八股-神經網絡相關

Deep-Learning-Interview-Book/docs/深度學習.md at master amusi/Deep-Learning-Interview-Book GitHub 網上相關總結&#xff1a; 小菜雞寫一寫基礎深度學習的問題&#xff08;復制大佬的&#xff0c;自己復習用&#xff09; - 知乎 (zhihu.com) CV面試問題準備持續更新貼 …

.net 調用海康SDK的跨平臺解決方案

??歡迎點贊 :?? 收藏 ?留言 ?? 如有錯誤敬請指正,賜人玫瑰,手留余香!??本文作者:由webmote 原創??作者格言:新的征程,我們面對的不僅僅是技術還有人心,人心不可測,海水不可量,唯有技術,才是深沉黑夜中的一座閃爍的燈塔序言 上2篇海康SDK使用以及常見的坑…

PCL 點云PFH特征描述子

點云PFH特征描述子 一、概述1.1 概念1.2 算法原理一、代碼實現二、結果示例一、概述 1.1 概念 點特征直方圖PFH(Point Feature Histograms)描述子:用于表示點云中每個點的局部幾何形狀信息,它是一種直方圖描述子,包括了點云的法線方向和曲率信息,PFH描述子可以幫助區分不同…

深入Django(八)

掌握Django的管理后臺 引言 在前七天的教程中&#xff0c;我們介紹了Django的基礎架構、模型、視圖、模板、URL路由、表單系統以及數據庫遷移。今天&#xff0c;我們將深入了解Django的管理后臺&#xff0c;這是一個功能強大的內置管理界面&#xff0c;用于創建、更新、查看和…

【JavaEE精煉寶庫】文件操作(1)——基本知識 | 操作文件——打開實用性編程的大門

目錄 一、文件的基本知識1.1 文件的基本概念&#xff1a;1.2 樹型結構組織和目錄&#xff1a;1.3 文件路徑&#xff08;Path&#xff09;&#xff1a;1.4 二進制文件 VS 文本文件&#xff1a;1.5 其它&#xff1a; 二、Java 操作文件2.1 方法說明&#xff1a;2.2 使用演示&…

QT面試筆記總計

一 Qt 保證多線程安全? 使互斥鎖保證多線程安全性。QMutex類、。使用讀寫鎖保證多線程安全性&#xff0c;QReadWriteLock。使用信號和槽機制保證多線程安全性。使用顯示切換保證多線程安全性。QTread類。 Qt 中的事件與信號的區別? 事件與信號的實現機制不同&#xff1b;事…

HCIA綜合實驗

學習新思想&#xff0c;爭做新青年。今天學習的是HCIA綜合實驗&#xff01; 實驗拓撲 實驗需求 總部&#xff1a; 1、除了SW8 SW9是三層交換機&#xff0c;其他交換機均為2層交換機。 2、GW為總部的出口設備&#xff0c;使用單臂路由技術&#xff0c;VLAN10,20,100的網關都在GW…

ERROR: “armeabi-v7a“ not supported for HarmonyOS

IDE 從 devecostudio-mac-4.1.3.700 升級至 devecostudio-mac-5.0.3.403 后拋出了如下異常: ERROR: "armeabi-v7a" not supported for HarmonyOS. 解決辦法 一.entry/build-profile.json5 需 entry/build-profile.json5 的 abiFilters 中移除 "armeabi-v7a&qu…

計算機網絡體系結構詳解:協議與分層

在學習計算機網絡時&#xff0c;理解網絡協議與分層體系結構是至關重要的。本文將詳細介紹這些概念&#xff0c;幫助基礎小白快速入門。 1. 什么是網絡協議 網絡協議是計算機網絡中用于數據交換的規則和標準。這些規則規定了數據格式、時序以及發送和接收數據時的動作。網絡協…

Unity3D瓦片地圖輔助定位工具

介紹 該工具用于TileMap的瓦片輔助定位&#xff0c;通過鍵盤或鼠標按瓦片尺寸0到1的比例作為單次移動值移動定位點游戲對象。當采用定位點游戲對象映射瓦片時&#xff0c;可使用該工具來移動定位點游戲對象&#xff0c;在新版本Unity3D的TileMap編輯器中可使用GameObject Brush…

基于java+springboot+vue實現的流浪動物管理系統(文末源碼+Lw)277

摘 要 在如今社會上&#xff0c;關于信息上面的處理&#xff0c;沒有任何一個企業或者個人會忽視&#xff0c;如何讓信息急速傳遞&#xff0c;并且歸檔儲存查詢&#xff0c;采用之前的紙張記錄模式已經不符合當前使用要求了。所以&#xff0c;對流浪動物信息管理的提升&…