Skip to content

Instantly share code, notes, and snippets.

@MaxenceMottard
Created October 3, 2023 13:38
Show Gist options
  • Save MaxenceMottard/dd91ed51d02f2391989c645f2f905c13 to your computer and use it in GitHub Desktop.
Save MaxenceMottard/dd91ed51d02f2391989c645f2f905c13 to your computer and use it in GitHub Desktop.
public extension View {
func readSize(_ size: Binding<CGSize>) -> some View {
modifier(ReadSizeModifier(size: size))
}
func readSize(onChange: @escaping (CGSize) -> Void) -> some View {
background(
GeometryReader { geometryProxy in
Color.clear
.preference(key: SizePreferenceKey.self, value: geometryProxy.size)
}
)
.onPreferenceChange(SizePreferenceKey.self, perform: onChange)
}
}
private struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
private struct ReadSizeModifier: ViewModifier {
@Binding var size: CGSize
func body(content: Content) -> some View {
content
.readSize(onChange: { newSize in
size = newSize
})
}
}
let values = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90 , 100]
struct SliderText: View {
@State var size: CGSize = .zero
let text: String
let isFirst: Bool
var offset: CGFloat {
size.width / 2
}
var body: some View {
Text(text)
.readSize($size)
.frame(maxWidth: .infinity, alignment: .center)
.background(Color.random())
// .offset(x: isFirst ? -offset : offset)
}
}
public extension Color {
static func random(randomOpacity: Bool = false) -> Color {
Color(
red: .random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1),
opacity: randomOpacity ? .random(in: 0...1) : 1
)
}
}
struct Preview: View {
@State var size: CGSize = .zero
var body: some View {
VStack {
HStack(spacing: 0) {
ForEach(values, id: \.self) { item in
Circle()
.fill(.white)
.frame(width: 5, height: 5)
if item != values.last {
Spacer()
}
}
}
.background(.green)
.cornerRadius(5)
HStack(spacing: 0) {
ForEach(values, id: \.self) { item in
SliderText(
text: "\(item)",
isFirst: values.first == item
)
.readSize($size)
}
}
.padding(.horizontal, -size.width/2)
}
.padding(.horizontal, size.width/2)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment