我尝试在SwiftUI中创建一个可扩展的分段选取器,到目前为止我已经完成了以下操作:
struct CustomSegmentedPicker: View {
@Binding var preselectedIndex: Int
@State var isExpanded = false
var options: [String]
let color = Color.orange
var body: some View {
HStack {
ScrollView(.horizontal) {
HStack(spacing: 4) {
ForEach(options.indices, id:\.self) { index in
let isSelected = preselectedIndex == index
ZStack {
Rectangle()
.fill(isSelected ? color : .white)
.cornerRadius(30)
.padding(5)
.onTapGesture {
preselectedIndex = index
withAnimation(.easeInOut(duration: 0.5)) {
isExpanded.toggle()
}
}
}
.shadow(color: Color(UIColor.lightGray), radius: 2)
.overlay(
Text(options[index])
.fontWeight(isSelected ? .bold : .regular)
.foregroundColor(isSelected ? .white : .black)
)
.frame(width: 80)
}
}
}
.transition(.move(edge: .trailing))
.frame(width: isExpanded ? 80 : CGFloat(options.count) * 80 + 10, height: 50)
.background(Color(UIColor.cyan))
.cornerRadius(30)
.clipped()
Spacer()
}
}
}
这给出了以下结果:
现在,当它收缩时,我如何保持显示选中的项目并隐藏其他项目?(目前,左侧的项目在未展开时总是显示)
2条答案
按热度按时间pb3skfrl1#
做得好,你可以在
ScollView
的内容中添加一个.offset()
,它会根据选择向左移动:pod7payv2#
下面是使用
.matchedGeometryEffect
的另一种方法,它可以处理不同的标签宽度,而不必退回到GeometryReader
。根据expansionState,它可以只绘制选定的项目或绘制所有项目,
.matchedGeometryEffect
确保动画流畅。