簡體   English   中英

水平滾動視圖在 SwiftUI 中在更改時垂直反彈

[英]Horizontal ScrollView bounces vertically in SwiftUI on change

我在 iOS 15 中的ScrollView有問題。使用scrollTo ,項目垂直彈跳。

我在 iOS 14 中沒有這個問題。反彈是非常隨機的,根本沒有邏輯來試圖理解它何時會跳躍。

如果我從滾動視圖中刪除填充,它是固定的,但我需要 UI 設計師要求的額外空間。

此外,試圖用.frame代替.padding和相同的結果。

有誰知道如何解決這個問題,或者為什么它只在 iOS 15 中發生?

滾動視圖錯誤

代碼:

ScrollView(.horizontal, showsIndicators: false) {
    
    ScrollViewReader{ proxy in
        HStack(spacing: 32){
            ForEach(...){ index in
                QuestionCell(...)
                    .scaleEffect(selectedIndex == index ? 1.175 : 1.0)
                    .onTapGesture{
                        withAnimation(.spring()){
                            
                            selectedIndex = index
                        }
                    }
            }
            
        }
        .padding(.leading)
        .padding() // Removing this fixes the bounce bug.
        .onChange(of: selectedIndex) { value in
        
            withAnimation(.spring()){
              let paramsCount = <SOME MODEL>.count
            
              if value < paramsCount{
                  proxy.scrollTo(value, anchor: .center)
              }else{
                  proxy.scrollTo(paramsCount - 1, anchor: .center)
              }
            }
         }
    }
}
}

問題是HStack上的垂直填充。

問題的最小可重現示例

這是任何人都可以運行的最少代碼的問題。 使用此代碼作為參考,看看有什么變化:

struct ContentView: View {
    @State private var selectedIndex = 0

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            ScrollViewReader { proxy in
                HStack(spacing: 32) {
                    ForEach(0 ..< 10, id: \.self) { index in
                        Text("Question cell at index: \(index)")
                            .background(Color(UIColor.systemBackground))
                            .scaleEffect(selectedIndex == index ? 1.175 : 1.0)
                            .onTapGesture {
                                withAnimation(.spring()) {
                                    selectedIndex = index
                                    proxy.scrollTo(index, anchor: .center)
                                }
                            }
                    }
                }
                .padding(.leading)
                .padding() // Removing this fixes the bounce bug
            }
        }
        .background(Color.red)
    }
}

解決方案

您可以通過執行.horizontal padding 從HStack刪除垂直填充,然后將.vertical padding 添加到每個Text視圖。

代碼:

struct ContentView: View {
    @State private var selectedIndex = 0

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            ScrollViewReader { proxy in
                HStack(spacing: 32) {
                    ForEach(0 ..< 10, id: \.self) { index in
                        Text("Question cell at index: \(index)")
                            .background(Color(UIColor.systemBackground))
                            .scaleEffect(selectedIndex == index ? 1.175 : 1.0)
                            .onTapGesture {
                                withAnimation(.spring()) {
                                    selectedIndex = index
                                    proxy.scrollTo(index, anchor: .center)
                                }
                            }
                            .padding(.vertical) // <- HERE
                    }
                }
                .padding(.leading)
                .padding(.horizontal) // <- HERE
            }
        }
        .background(Color.red)
    }
}
前 后

proxy.scrollTo(index, anchor: ...)使用.bottom而不是.center


如果我們設置 .top 或 .center 錨點,則在proxy.scrollTo動畫期間垂直內容偏移會發生變化。 它看起來像一些蘋果蟲。 為了避免這種情況,我們應該對齊這樣的錨點,這會在滾動期間導致零偏移。

對於水平 ScrollView 我們應該改變:

  • .trailing -> .bottomTrailing
  • .center -> .bottom
  • .lead -> .bottomLeading

對於垂直:

  • .top -> .topTrailing
  • .center -> .trailing
  • .bottom -> .bottomTrailing

暫無
暫無

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

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