listless

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

PlatformScrollIndicatorsModifier.swift (1338B)


      1 import SwiftUI
      2 
      3 private struct ContentHeightKey: 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 PlatformScrollIndicatorsModifier: ViewModifier {
     12     let verticalPadding: CGFloat
     13     @State private var contentHeight: CGFloat = 0
     14 
     15     func body(content: Content) -> some View {
     16         GeometryReader { proxy in
     17             let effectiveContentHeight = max(0, contentHeight - (verticalPadding * 2))
     18             content
     19                 .background(
     20                     GeometryReader { contentProxy in
     21                         Color.clear.preference(
     22                             key: ContentHeightKey.self, value: contentProxy.size.height)
     23                     }
     24                 )
     25                 .scrollIndicators(effectiveContentHeight > proxy.size.height ? .visible : .hidden)
     26                 .onPreferenceChange(ContentHeightKey.self) { height in
     27                     if height != contentHeight {
     28                         contentHeight = height
     29                     }
     30                 }
     31         }
     32     }
     33 }
     34 
     35 extension View {
     36     func platformScrollIndicators(verticalPadding: CGFloat = 0) -> some View {
     37         modifier(PlatformScrollIndicatorsModifier(verticalPadding: verticalPadding))
     38     }
     39 }