Created
October 3, 2023 13:38
-
-
Save MaxenceMottard/dd91ed51d02f2391989c645f2f905c13 to your computer and use it in GitHub Desktop.
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
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