SwiftUI:如何将scrollTransition的phase.isIdentity传递给@State布尔属性
问题描述
我在iOS 17环境下使用以下scrollTransition修饰符实现了视图的透明度与缩放动画,请问是否有办法将其中的phase.isIdentity值传递给我的@State布尔类型属性?
.scrollTransition { view, phase in view.opacity(phase.isIdentity ? 1 : 0) .scaleEffect(phase.isIdentity ? 1 : 0.75) }
解决方案
完全可以实现,你只需要在scrollTransition的闭包内部直接更新@State属性就行,但要注意必须禁用动画上下文,不然会触发不必要的动画循环。
直接看代码示例:
struct ContentView: View { @State private var isInIdentityPhase = false var body: some View { ScrollView { VStack(spacing: 20) { ForEach(0..<10) { index in Text("Item \(index)") .frame(height: 100) .frame(maxWidth: .infinity) .background(Color.blue) .scrollTransition { view, phase in // 用withAnimation(nil)包裹赋值,避免动画循环 withAnimation(nil) { isInIdentityPhase = phase.isIdentity } // 保留原有的过渡动画逻辑 view.opacity(phase.isIdentity ? 1 : 0) .scaleEffect(phase.isIdentity ? 1 : 0.75) } } } } // 可以监听属性变化做后续操作 .onChange(of: isInIdentityPhase) { _, newValue in print("当前是否处于Identity阶段: \(newValue)") } } }
核心注意事项:
- 必须用
withAnimation(nil)包裹赋值操作,因为scrollTransition本身处于动画环境中,直接修改@State会触发视图重绘,进而再次执行过渡闭包,形成无限循环。 - 如果你需要更精准的时机,也可以根据
phase的其他状态(比如.topLeading、.bottomTrailing)来控制属性赋值,而不是只依赖isIdentity。
内容的提问来源于stack exchange,提问作者Tinn_Vision
相关产品推荐
相关产品推荐

