日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SwiftUI之深入解析如何定制视图的动画和转场

發布時間:2024/5/28 编程问答 74 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SwiftUI之深入解析如何定制视图的动画和转场 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

  • 使用 SwiftUI 可以把視圖狀態的改變轉成動畫過程,SwiftUI 會處理所有復雜的動畫細節。
  • 本文中,會給跟蹤用戶徒步的圖表視圖添加動畫,使用 animation(_: ) 修改器給一個視圖添加動畫效果非常容易。
  • 可以下載文末的示例代碼并跟著本篇教程一步步實踐,或者查看本篇完成狀態時的工程代碼去學習,就可以輕松完成視圖的動畫添加和轉場動畫設定。

二、給每個視圖單獨添加動畫

  • 在視圖上使用 animation(_: ) 修改器時,SwiftUI 會在視圖的任何可進行動畫的屬性發生改變時產生對應的動畫效果。視圖的顏色、不透明度、旋轉角度、大小及一些其它屬性都是可進行動畫的:

  • 在 HikeView.swift 中,打開實時預覽,體驗一下圖表的打開和隱藏,此時的狀態改變時是沒有添加動畫效果的。在本文中,保持實時預覽一直打開,每一步修改的效果就可以實時的看到:

  • 給顯示/隱藏切換的箭頭按鈕添加旋轉動畫,會發現現在按鈕點擊時的旋轉有一個動畫過渡的效果:
struct HikeView: View {var hike: Hike@State private var showDetail = falsevar body: some View {VStack {HStack {HikeGraph(hike: hike, path: \.elevation).frame(width: 50, height: 30).animation(nil)VStack(alignment: .leading) {Text(hike.name).font(.headline)Text(hike.distanceText)}Spacer()Button(action: {withAnimation {self.showDetail.toggle()}}) {Image(systemName: "chevron.right.circle").imageScale(.large).rotationEffect(.degrees(showDetail ? 90 : 0)).scaleEffect(showDetail ? 1.5 : 1).padding().animation(.easeInOut)}}if showDetail {HikeDetail(hike: hike)}}} }struct HikeView_Previews: PreviewProvider {static var previews: some View {VStack {HikeView(hike: hikeData[0]).padding()Spacer()}} }

  • 當視圖從隱藏到展示時,讓切換按鈕變大 1.5 倍:

  • 把動畫的類型從 easeInOut 改為 spring(),SwiftUI 包含一些預設或可自定義的動畫類型,像彈簧(spring)動畫和類型液體(fluid)動畫類型,可以調整動畫開始前的等待時長、動畫的速度也可以指定讓動畫循環重復的進行:

  • 如果只想讓按鈕具有縮放動畫而不進行旋轉動畫,可以在 scaleEffect 添加 animation(nil) 來實現。可以在這里做一些實驗,如果把其它的一些動畫效果結合在一起,會怎么樣呢?

三、把視圖的狀態改態轉化成動畫效果

  • 學會給單個視圖添加動畫的方法,現在可以學習怎么在視圖的狀態發生改變時添加動畫效果,當用戶點擊按鈕時會切換 showDetail 狀態的值,在視圖變化過程中添加動畫效果:

  • 把 showDetail.toggle() 包裹在 withAnimation 函數調用塊中。showDetail 的改變影響了視圖 HikeDetail 和詳情切換按鈕,在顯示/隱藏詳情的過程中都有了過濾動畫效果:

  • 放慢動畫速度,可以觀察 SwiftUI 動畫在被中斷下是怎么運作的,給 withAnimation 傳入一個時長4秒的基本動畫參數 .easeInOut(duration:4),可以指定動畫過程時長,給 withAnimation 傳入的動畫參數與 .animation(_😃 修改器可用參數一致:

  • 在動畫過程進行中點擊按鈕切換視圖狀態,查看對應的動畫被中斷時的效果:

四、定制視圖轉場動畫

  • 開始之前,先把動畫時長參數 (.easeInOut(duration: 4)) 相關的代碼去掉,讓動畫不再緩慢進行。
  • 默值情況下,視圖離屏和入屏時的動畫效果是漸隱/漸現, 這個默認的轉場效果可以使用 transition(_: ) 修改器進行定制:

  • 給 HikeView 視圖添加 transition(_: ) 修改器,并定制轉場參數為 .slide,轉場動畫為滑入/滑出:

  • 可以把滑入/滑出這種轉場動畫封裝起來,方便其它視圖復用同樣的轉場效果:
extension AnyTransition {static var moveAndFade : AnyTransition {AnyTransition.slide} }struct HikeView: View {var hike: Hike@State private var showDetail = falsevar body: some View {VStack {HStack {HikeGraph(hike: hike, path: \.elevation).frame(width: 50, height: 30).animation(nil)VStack(alignment: .leading) {Text(hike.name).font(.headline)Text(hike.distanceText)}Spacer()Button(action: {withAnimation() {self.showDetail.toggle()}}) {Image(systemName: "chevron.right.circle").imageScale(.large).rotationEffect(.degrees(showDetail ? 90 : 0)).scaleEffect(showDetail ? 1.5 : 1).padding()}}if showDetail {HikeDetail(hike: hike).transition(.moveAndFade)}}} }
  • 在 moveAndFade 轉場效果的定義中使用 move(edge:),讓滑入/滑出從屏幕的同一邊進行:

  • 使用 asymmetric(insertion:removal: ) 修改器來定制視圖顯示/消失時的轉場動畫效果:

五、組合復雜的動畫效果

  • 點擊圖表下面的三個按鈕,會在三個不同的數據集間進行切換并展示。現在使用組合動畫,讓圖表在不同數據集間切換時的轉換動畫流暢自然:

  • 把 showDetail 的默認值改為 true,并把 HikeView 的預覽模式視圖固定在畫布上。這樣可以在編輯其它文件時,依然看到動畫效果的變化:

  • 在 HikeGraph.swift 中定義了一個新的波動動畫,并把它與滑入/滑出動畫一起應用到圖表視圖上:
func magnitude(of range: Range<Double>) -> Double {return range.upperBound - range.lowerBound }extension Animation {static func ripple() -> Animation {Animation.default} }struct HikeGraph: View {var hike: Hikevar path: KeyPath<Hike.Observation, Range<Double>>var color: Color {switch path {case \.elevation:return .graycase \.heartRate:return Color(hue: 0, saturation: 0.5, brightness: 0.7)case \.pace:return Color(hue: 0.7, saturation: 0.4, brightness: 0.7)default:return .black}}var body: some View {let data = hike.observationslet overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] })let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()!let heightRatio = (1 - CGFloat(maxMagnitude / magnitude(of: overallRange))) / 2return GeometryReader { proxy inHStack(alignment: .bottom, spacing: proxy.size.width / 120) {ForEach(data.indices) { index inGraphCapsule(index: index,height: proxy.size.height,range: data[index][keyPath: self.path],overallRange: overallRange).colorMultiply(self.color).transition(.slide).animation(.ripple())}.offset(x: 0, y: proxy.size.height * heightRatio)}}} }
  • 把動畫切換為彈簧動畫(spring),并設置彈簧阻尼系數為 0.5,動畫過程中產生了逐漸回彈效果:

  • 加速彈簧動畫的執行速度,縮短切換圖表的時間:

  • 以當條形在圖表中的位置為參數,添加延遲效果,圖表中的每個條形會順序動起來:

  • 觀察一下自定義波動(rippling)效果是怎么作用在視圖轉場中的。
與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的SwiftUI之深入解析如何定制视图的动画和转场的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。