listless

A simple list app for Apple platforms
Log | Files | Refs | README | LICENSE

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 }