簡體   English   中英

滾動視圖中的 SwiftUI 動畫/過渡表現奇怪

[英]SwiftUI animation/transition within scrollview behaving strange

我在 SwiftUI 中有一個帶有多個元素的 ScrollView,其中一些元素可以在點擊時展開。

struct ExpandingView: View {

    @State var showContent = false

    var body: some View {
        VStack {
            HStack {
                Button(action: {withAnimation {
                        self.showContent.toggle()
                    }
                }) {
                    Image(systemName: "chevron.right.circle")
                }
                Text("TITLE")
                    .padding(.leading, 10)
                Spacer()
            }
            if showContent {
                Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras volutpat dapibus ante eget laoreet. Aenean lacus elit, auctor ut nisl id, fermentum pretium mi. Quisque lacus nisl, suscipit hendrerit est sed, congue dictum augue. Suspendisse semper viverra accumsan. Maecenas commodo turpis convallis nisl bibendum pharetra.")
                    .transition(AnyTransition.move(edge: .top).combined(with: .opacity))
            }
        }
    }
}

struct Test: View {

    var body: some View {
        ScrollView {
            ExpandingView()
            ExpandingView()
            ExpandingView()
            Text("Some static text")
        }
    }
}

如果您嘗試打開其中一個展開的文本,您會看到過渡並不順暢,有點像跳躍,然后過渡開始。

問題1

所以這是我嘗試過的:

  • 如果我刪除滾動視圖並將其放到 VStack 中,例如它工作正常,但這不是一個選項,因為我有更多的元素不適合屏幕。
  • 我嘗試為滾動視圖設置 animation 因為我讀到它解決了此類問題,如下所示:
ScrollView {
            ExpandingView()
            ExpandingView()
            ExpandingView()
            Text("Some static text")
        }.animation(.spring())

它在打開過渡方面效果很好,使用 spring 效果甚至看起來更好,但是 spring animation 在視圖出現時不播放整個滾動視圖。

問題2

同樣,如果我將 ScrollView 更改為 VStack,animation 不會在出現時播放,這很好,但我必須使用滾動視圖。 所以對我來說最好的解決方案是保留 animation 來打開文本,但在視圖出現時以某種方式將其刪除。

這是可能的解決方案。 另請閱讀內聯評論。 使用 Xcode 11.4 / ISO 13.4 測試

演示

struct ExpandingView: View {

    @State var showContent = false

    var body: some View {
        VStack {
            HStack {
                Button(action: {
                        self.showContent.toggle()
                }) {
                    Image(systemName: "chevron.right.circle")
                }
                Text("TITLE")
                    .padding(.leading, 10)
                Spacer()
            }
            if showContent {
                Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras volutpat dapibus ante eget laoreet. Aenean lacus elit, auctor ut nisl id, fermentum pretium mi. Quisque lacus nisl, suscipit hendrerit est sed, congue dictum augue. Suspendisse semper viverra accumsan. Maecenas commodo turpis convallis nisl bibendum pharetra.")
                    .fixedSize(horizontal: false, vertical: true)
                    .transition(AnyTransition.move(edge: .top).combined(with: .opacity))
            }
        }
    }
}

struct DemoExpandingView: View {

    // initial nil to avoid initial animation
    @State private var animation: Animation? = nil
    var body: some View {
        ScrollView {
            VStack {
                ExpandingView()
                ExpandingView()
                ExpandingView()
                Text("Some static text")
            }.animation(animation) // << needed to animate static section
        }
        .onAppear {
            DispatchQueue.main.async {
                // assign in-container animation `after` container rendered
                self.animation = .default
            }
        }
    }
}

備份

暫無
暫無

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

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