PlatformTextFieldWidthModifier.swift (1473B)
1 import SwiftUI 2 3 private struct TextFieldWidthPreferenceKey: PreferenceKey { 4 static let defaultValue: CGFloat = 0 5 6 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { 7 value = max(value, nextValue()) 8 } 9 } 10 11 private struct MacTextFieldWidthModifier: ViewModifier { 12 let text: String 13 let placeholder: String 14 15 @State private var measuredWidth: CGFloat = 60 16 17 func body(content: Content) -> some View { 18 content 19 .frame(width: max(44, measuredWidth + 12), alignment: .leading) 20 .background(widthMeasurer) 21 .onPreferenceChange(TextFieldWidthPreferenceKey.self) { width in 22 if width > 0, width != measuredWidth { 23 measuredWidth = width 24 } 25 } 26 } 27 28 private var widthMeasurer: some View { 29 Text(displayText) 30 .font(.body) 31 .lineLimit(1) 32 .fixedSize() 33 .background( 34 GeometryReader { proxy in 35 Color.clear.preference( 36 key: TextFieldWidthPreferenceKey.self, value: proxy.size.width) 37 } 38 ) 39 .hidden() 40 } 41 42 private var displayText: String { 43 text.isEmpty ? placeholder : text 44 } 45 } 46 47 extension View { 48 func platformTextFieldWidth(text: String, placeholder: String) -> some View { 49 modifier(MacTextFieldWidthModifier(text: text, placeholder: placeholder)) 50 } 51 }