Been trying to find a solution to dynamically detect the Background Color / the color underneath the View you want to modify, since I may want to have readable text over a Image without resorting to using an average color of a Image to determine the right color for the text because some images may have more light colours in certain places in a Image, vice versa with Dark Colors, so is there a way to get the color at a certain Coord then use that to determine what the Text Color should be, tried using Grok etc to generate a basis which got me so far but there isn’t a Color function in the GeomertyReader since it wants me to use that Response from Grok.
struct BackgroundColorKey: PreferenceKey {
static var defaultValue: Color? = nil
static func reduce(value: inout Color?, nextValue: () -> Color?) {
value = nextValue()
}
}
struct BackgroundColorReader: View {
var body: some View {
GeometryReader { geometry in
Color.clear
.preference(key: BackgroundColorKey.self, value: geometry.color(at: geometry.frame(in: .local).center))
}
}
}
struct DynamicTextColor: View {
@State private var backgroundColor: Color? = nil
var body: some View {
VStack {
Text("Your Text Here")
.foregroundColor(backgroundColor?.luminance < 0.5 ? .white : .black) // Invert based on luminance
.background(
BackgroundColorReader()
.onPreferenceChange(BackgroundColorKey.self) { newColor in
self.backgroundColor = newColor
}
)
}
}
}
That’s the Code it generated, also looked endlessly online if someone else had a solution nothing, so is there a Framework or a solution that could be used for both macOS & iOS.
This is an Example I’m trying to solve in SwiftUI I have Below
2
Answers
try this:
result:
Code taken from: https://designcode.io/swiftui-handbook-multiple-blending-modes
IMHO: Better to do not use color inversion / blending.
Better to do outline effect around text. (black text – white outline OR white text – black outline.)
When you use
.blendMode
it effectively examines the image on a pixel-by-pixel basis for you. Some notes:The documentation for the enum
BlendMode
is basic, to say the least. However, you will find better documentation for the different modes under GraphicsContext.BlendMode.Use
.compositingGroup()
to limit the scope with which the blend mode works. In particular, this can be used to stop it from going to lower layers, or for combining different blend mode effects.Here is an example based on your sample image:
If you really want to do the image analysis yourself, this answer shows how to get the color values at a particular pixel position.