Skip to content

Instantly share code, notes, and snippets.

@mayoff
Created August 12, 2021 04:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mayoff/c13926d9ee8ae0cfccb58d3b2f046350 to your computer and use it in GitHub Desktop.
Save mayoff/c13926d9ee8ae0cfccb58d3b2f046350 to your computer and use it in GitHub Desktop.
Complete code for https://stackoverflow.com/a/68751668/77567 (EqualIconWidthDomain for SwiftUI Label views)
import SwiftUI
fileprivate struct IconWidthKey: PreferenceKey {
static var defaultValue: CGFloat? { nil }
static func reduce(value: inout CGFloat?, nextValue: () -> CGFloat?) {
switch (value, nextValue()) {
case (nil, let next): value = next
case (_, nil): break
case (.some(let current), .some(let next)): value = max(current, next)
}
}
}
extension IconWidthKey: EnvironmentKey { }
extension EnvironmentValues {
fileprivate var iconWidth: CGFloat? {
get { self[IconWidthKey.self] }
set { self[IconWidthKey.self] = newValue }
}
}
fileprivate struct IconWidthModifier: ViewModifier {
@Environment(\.iconWidth) var width
func body(content: Content) -> some View {
content
.background(GeometryReader { proxy in
Color.clear
.preference(key: IconWidthKey.self, value: proxy.size.width)
})
.frame(width: width)
}
}
struct EqualIconWidthLabelStyle: LabelStyle {
func makeBody(configuration: Configuration) -> some View {
HStack {
configuration.icon.modifier(IconWidthModifier())
configuration.title
}
}
}
struct EqualIconWidthDomain<Content: View>: View {
let content: Content
@State var iconWidth: CGFloat? = nil
init(@ViewBuilder _ content: () -> Content) {
self.content = content()
}
var body: some View {
content
.environment(\.iconWidth, iconWidth)
.onPreferenceChange(IconWidthKey.self) { self.iconWidth = $0 }
.labelStyle(EqualIconWidthLabelStyle())
}
}
struct ContentView: View {
var body: some View {
EqualIconWidthDomain {
VStack(alignment: .leading) {
Label("People", systemImage: "person.3")
Label("Star", systemImage: "star")
Label("This is a plane", systemImage: "airplane")
}
}
}
}
struct Demo_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct FancyView: View {
var body: some View {
EqualIconWidthDomain {
VStack {
Text("Le Menu")
.font(.caption)
Divider()
HStack {
VStack(alignment: .leading) {
Label(
title: { Text("Strawberry") },
icon: { Text("🍓") })
Label("Money", systemImage: "banknote")
}
VStack(alignment: .leading) {
Label("People", systemImage: "person.3")
Label("Star", systemImage: "star")
}
}
}
}
}
}
struct Demo_Previews_2: PreviewProvider {
static var previews: some View {
FancyView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment