考慮以下示例:
struct ContentView: View {
@State var showSplash: Bool = true
@Namespace var animationNamespace
var body: some View {
ZStack {
if showSplash {
GeometryReader { geometry in
AsyncImage(url: URL(string: "https://picsum.photos/seed/864a5875-6d8b-43d6-8d65-04c5cfb13f3b/1920/1440")) { image in
image.resizable()
.scaledToFill()
.matchedGeometryEffect(id: "SplashImage", in: animationNamespace)
.transition(.move(edge: .bottom))
.frame(width: geometry.size.width)
.transition(.move(edge: .bottom))
.edgesIgnoringSafeArea(.all)
.clipped()
} placeholder: {
Color.gray
}
}
.onTapGesture {
toggleSplashScreen(false)
}
} else {
ScrollView {
GeometryReader { geometry in
AsyncImage(url: URL(string: "https://picsum.photos/seed/864a5875-6d8b-43d6-8d65-04c5cfb13f3b/1920/1440")) { image in
image
image
.resizable()
.scaledToFill()
.matchedGeometryEffect(id: "SplashImage", in: animationNamespace)
.transition(.move(edge: .bottom))
} placeholder: {
Color.gray
}
.frame(width: geometry.size.width, height: 400)
.clipped()
}
.edgesIgnoringSafeArea(.all)
.onTapGesture {
toggleSplashScreen(true)
}
}
}
}
}
}
在這里使用輔助方法:
private extension ContentView {
func toggleSplashScreen(_ toggle: Bool) {
withAnimation(.spring(response: 0.85, dampingFraction: 0.95)) {
showSplash = toggle
}
}
}
這產生:

我注意到這里有兩件事我想修復
- 在兩種狀態之間轉換時的閃爍白色效果。
- 我注意到,因為我們正在使用
AsyncImage,當showSplash更改 AsyncImages 時,只是有時會碰到placeholder塊。結果,過渡變得非常不穩定。我使用資產檔案中的靜態影像對此進行了測驗,然后過渡變得平滑。我還嘗試在 AsyncImage 上創建快取機制,但placeholder有時仍然遇到阻塞的問題。
很想聽聽任何想法:) 謝謝!
uj5u.com熱心網友回復:
我認為您可以采取一些措施來改善這一點。
首先,您正在與 SwiftUI 維護視圖示識的方式作斗爭。SwiftUI 確定何時可以重用現有結構而不是重新創建結構的方法之一是根據它在視圖層次結構中的位置。所以當你切換你的結構時,你會從:
GeometryReader
AsyncImage
到
ScrollView
GeometryReader
AsyncImage
結果,系統認為這是兩個AsyncImage視圖,因此每次都重建視圖(并重新加載影像)。我認為這就是您的白色閃光的來源,因為您在影片中間看到了灰色占位符。如果您可以將滾動視圖保留在原位,可能在不需要時禁用滾動(如果可能),那么作業系統可以保持AsyncImage. (參見https://developer.apple.com/videos/play/wwdc2021/10022/)
這為您帶來了第二個調查領域。 AsyncImage它為您從網路加載內容提供了便利。不幸的是,它并沒有使這種通信更快。您的目標應該是AsyncImage盡可能少地訪問網路。
現在,您的調整大小策略側重于調整影像大小。這意味著對于每次轉換,您都在“訪問網路”(閱讀將您的代碼放在緩慢、塵土飛揚、泥濘的道路上)。您應該只加載一次影像(慢速部分)并調整顯示它的視圖的大小,而不是調整影像大小。一般的想法是讓AsyncImage加載影像,然后通過影片視圖的框架來控制影像的影片方式。
這是我不太有用的地方。我不太了解AsyncImage它是否能夠實施該策略。似乎應該是……但我不知道是不是。您可能不得不求助于下載和存盤影像作為獨立于呈現它的視圖的狀態。
所以我的建議是限制AsyncImage必須重新加載網路資料的次數。這涉及幫助 SwiftUI 維護 的身份,AsyncImage因此不必在每次創建視圖時重新加載。并且,嘗試在視圖而不是影像上實作影片和縮放,因為重新縮放影像還需要重新加載網路。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/334839.html
標籤:ios 迅捷 ios15 swiftui-几何效果 swiftui-asyncimage
