Created
September 27, 2021 19:00
-
-
Save liudasbar/ff0c74dbd651a0b7239b4d9931a97760 to your computer and use it in GitHub Desktop.
SwiftUI Custom Segmented Control with animation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct CustomSegmentedControl: View { | |
@Binding var arrayOfItems: [Item] | |
@Binding var selection: Item | |
@State private var frames: [CGRect] = Array(repeating: .zero, count: 3) | |
var body: some View { | |
ScrollView(.horizontal, showsIndicators: false, content: { | |
HStack(spacing: 0) { | |
ForEach(arrayOfItems.indices, id: \.self) { index in | |
Button( | |
arrayOfItems[index], | |
action: { | |
selection = arrayOfItems[index] | |
}) | |
.font(.body) | |
.foregroundColor(selection == arrayOfItems[index] ? Color.black : Color.gray) | |
.padding([.leading, .trailing], 16) | |
.padding([.top, .bottom], 5) | |
.buttonStyle(PlainButtonStyle()) | |
.background( | |
GeometryReader { geo in | |
Color.clear.onAppear { self.setFrame(index: index, frame: geo.frame(in: .global)) } | |
} | |
) | |
} | |
} | |
.padding([.leading, .trailing], 16) | |
.padding([.top, .bottom], 30) | |
.background( | |
Rectangle() | |
.fill(Color.white) | |
.cornerRadius(8) | |
.frame( | |
width: self.frames[selectionIndex()].width, | |
height: 30, | |
alignment: .center | |
) | |
.offset(x: self.frames[selectionIndex()].minX - self.frames[0].minX + 16), | |
alignment: .leading | |
) | |
.animation(.easeInOut(duration: 0.2)) | |
}) | |
} | |
private func selectionIndex() -> Int { | |
for (index, item) in arrayOfItems.enumerated() where item == selection { | |
return index | |
} | |
return 0 | |
} | |
private func setFrame(index: Int, frame: CGRect) { | |
self.frames[index] = frame | |
} | |
} |
Source for any troubleshooting: https://stackoverflow.com/questions/60804512/swiftui-create-a-custom-segmented-control-also-in-a-scrollview/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In case any visual issues appear, make sizes the constants.
Example: