SwiftUI:使用.matchedGeometry()实现自定义分段控件遇问题
解决SwiftUI自定义分段控件滑动动画问题
你的问题核心是只有选中状态的按钮才渲染背景矩形,而matchedGeometryEffect需要动画前后两个状态下都存在对应的视图实例才能实现平滑过渡。以下是修复方案:
关键修改点
- 给每个按钮都添加背景矩形,未选中时通过透明色隐藏,确保动画前后视图始终存在
- 保持
matchedGeometryEffect的ID和命名空间一致,让系统能识别需要过渡的目标视图
修复后的代码
@AppStorage("selectedcountry") private var selectedCountry: Country = .france @Namespace private var animation HStack { ForEach(Country.allCases, id: \.self) { country in Button { withAnimation(.easeInOut) { selectedCountry = country } } label: { Text(country.flag) .padding() .frame(maxWidth: .infinity) } .background { RoundedRectangle(cornerRadius: 10) .fill(selectedCountry == country ? Color.accentColor : Color.clear) .matchedGeometryEffect(id: "countryBg", in: animation) } } } .background(Color(.systemGray6)) .cornerRadius(10) .padding(.horizontal)
额外优化建议
- 显式指定
.easeInOut动画曲线,让滑动过渡更贴近iOS原生分段控件的流畅感 - 将
frame(maxWidth: .infinity)移到按钮label内部,确保文本区域和背景矩形的尺寸完全对齐 - 给外层HStack添加浅灰色背景和圆角,还原原生分段控件的视觉样式
内容的提问来源于stack exchange,提问作者Malburrito
相关产品推荐
相关产品推荐

