簡體   English   中英

僅在固定標題時自定義部分標題,否則不自定義(SwiftUI)

[英]Customise Section Headers ONLY when Headers are pinned, otherwise not (SwiftUI)

我的問題很簡單:有什么方法可以僅在固定部分的標題時自定義它,但如果沒有固定,則保持原樣?

我正在嘗試將 .shadow 添加到部分的標題中,並且我不希望它一直可見,但僅在開始向下滾動到父 ScrollView 中的標題時(當標題被固定時)。

我主要是在尋找一個純粹的 SwiftUI 解決方案,但我也願意討論其他解決方案。 :)

struct WorkoutCardView: View {
    @Binding var workout: Workout
    @State var expandWorkout: Bool = false
    
    @Environment(\.colorScheme) var colorScheme
    
    var body: some View {
        LazyVStack(alignment: .leading, pinnedViews: .sectionHeaders) {
            Section {
                if expandWorkout {
                    WCExerciseSectionView(workout: $workout)
                }
            } header: {
                WCTitleSectionView(workout: $workout)
                    .background {
                        Color(uiColor: .systemBackground)
                        Color(uiColor: .systemFill)
                    }
                    .cornerRadius(10)
                    .shadow(color: colorScheme == .light ?
                            Color.black.opacity(expandWorkout ? 0.6 : 0) :
                                Color.white.opacity(expandWorkout ? 0.6 : 0), radius: 5, x: 0, y: 2)
                    .padding(.all, 2)
            }
        }
        .padding(.all, 8)
        .background {
            RoundedRectangle(cornerRadius: 10)
                .fill(Color(uiColor: .systemFill))
        }
        .padding(.all, 8)
        .onTapGesture {
            withAnimation {
                expandWorkout.toggle()
            }
        }
    }
}

在此處查看當前結果

一種可能的方法是基於相對於容器坐標空間的標題位置的動態檢測,如果它為零(即固定在頂部),則相應地更改樣式。

使用 Xcode 13.4 / iOS 15.5 測試

演示

這是主要部分:

                } header: {
                    HeaderView(value: "HEADER \(i + 1)", pinned: i == pinned)
                        .background(GeometryReader {
                            // detect current position of header
                            Color.clear.preference(key: ViewOffsetKey.self,
                                value: $0.frame(in: .named("area")).origin.y)
                        })
                }
                .onPreferenceChange(ViewOffsetKey.self) {
                    // verify if position is zero (pinned) in container coordinates
                    if $0 == 0 {
                        self.pinned = i
                    } else if self.pinned == i {
                        // clean-up if changed (might depend - for simplicity)
                        self.pinned = nil
                    }
                }
            }
        }
    }.clipped()
}.coordinateSpace(name: "area")    // << here !!

GitHub 上的測試模塊

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM