iOS15 SwiftUI VStack设置value绑定动画后行未随动下压如何解决
修复方案
该问题的核心原因是:带value参数的animation修饰符仅会对当前视图范围内和绑定值相关的属性变化生效,不会触发父容器内其他兄弟视图的位置动画;而已废弃的无参数animation修饰符默认会关联所有布局变化,才会出现新旧API的表现差异。
推荐修复方式:使用withAnimation显式触发状态变更
将isOpen的切换逻辑用withAnimation包裹,所有和该状态关联的布局变化(包括分区高度变化导致的其他分区位移、内部子项的显隐动画)都会自动生效,不需要额外加animation修饰符。
修改后的代码如下:
import SwiftUI struct FilterTest: View { var body: some View { ScrollView{ HeaderCellTest() HeaderCellTest() HeaderCellTest() HeaderCellTest() Spacer() } } } struct HeaderCellTest: View { @State private var isOpen: Bool = false var body: some View { content .padding(.leading) .frame(maxWidth: .infinity) } private var content: some View { VStack(alignment: .leading, spacing: 8) { HStack { Text("HEADING") } .onTapGesture { // 用withAnimation包裹状态变更 withAnimation(.default) { isOpen.toggle() } } if isOpen { Group { Text("Item") Text("Item") Text("Item") Text("Item") Text("Item") } .padding(.leading) } Divider() } // 删掉原来的animation修饰符即可 } } struct FilterTest_Previews: PreviewProvider { static var previews: some View { FilterTest() } }
可选修复方式:调整动画修饰符层级
如果需要保留animation修饰符的写法,需要将所有分区的isOpen状态提取到父视图统一管理,再将animation修饰符挂载到ScrollView层级绑定对应的状态数组。该方案适合需要全局控制分区展开状态的场景,实现相对繁琐,无特殊需求优先使用第一种方案。
内容的提问来源于stack exchange,提问作者tunaahi333
相关产品推荐
相关产品推荐

