SwiftUI下拉列表箭头旋转动画偏离中心问题求助
SwiftUI下拉列表箭头旋转时上下偏移的解决方法
问题描述
在实现SwiftUI下拉列表项时,点击列表项展开/收起时,箭头图标会出现上下偏移的问题,无法围绕自身中心点平稳旋转。相关代码如下:
struct SomeObject: Hashable { var title: String = "title" var entries: [String] = ["details", "details2", "details3"] } struct ContentView: View { var data: [SomeObject] = [SomeObject()] var body: some View { List(data, id: \.self) { item in HStack { Text(item.title) Spacer() } ForEach(item.entries, id: \.self) { entry in ListItemView(entry) } }.listStyle(.plain) } } struct ListItemView: View { @State var expanded: Bool = false @State var rotation: Double = 0 private let entry: String init(_ entry: String) { self.entry = entry } var body: some View { VStack { Divider().frame(maxWidth: .infinity) .overlay(.black) HStack { Text(entry) .fixedSize(horizontal: false, vertical: true) Spacer() Image(systemName: "chevron.down") .foregroundColor(.black) .padding() .rotationEffect(.degrees(expanded ? 180 : 360)) .animation(.linear(duration: 0.3), value: expanded) }.padding(.horizontal) .padding(.vertical, 6) if expanded { Text("Details") } Divider().frame(maxWidth: .infinity) .overlay(.black) } .listRowSeparator(.hidden) .listRowInsets(.init()) .onTapGesture { expanded.toggle() } } }
解决方案
问题的核心是箭头视图在旋转过程中没有固定的尺寸边界,导致SwiftUI重新计算布局时出现位移。只需给箭头图标添加固定的frame,确保旋转时锚点稳定在自身中心即可:
修改后的ListItemView代码
struct ListItemView: View { @State var expanded: Bool = false private let entry: String init(_ entry: String) { self.entry = entry } var body: some View { VStack { Divider().frame(maxWidth: .infinity) .overlay(.black) HStack { Text(entry) .fixedSize(horizontal: false, vertical: true) Spacer() Image(systemName: "chevron.down") .foregroundColor(.black) .frame(width: 24, height: 24) // 固定视图尺寸,确保旋转边界稳定 .padding() .rotationEffect(.degrees(expanded ? 180 : 0)) // 用0替代360,逻辑更直观 .animation(.linear(duration: 0.3), value: expanded) }.padding(.horizontal) .padding(.vertical, 6) if expanded { Text("Details") } Divider().frame(maxWidth: .infinity) .overlay(.black) } .listRowSeparator(.hidden) .listRowInsets(.init()) .onTapGesture { expanded.toggle() } } }
关键修改点
- 给
Image添加.frame(width: 24, height: 24):固定箭头视图的尺寸,避免动画过程中布局边界变化导致位移 - 将旋转角度从
360改为0:360°和0°视觉效果一致,使用0°逻辑更清晰 - 移除了未使用的
rotation状态变量:简化代码结构
这样修改后,箭头会围绕自身中心点平稳旋转,不会出现上下偏移的问题。
内容的提问来源于stack exchange,提问作者Plays2
相关产品推荐
相关产品推荐

