在scrollview中的SwiftUI动画/过渡表现得很奇怪 [英] SwiftUI animation/transition within scrollview behaving strange

查看:160
本文介绍了在scrollview中的SwiftUI动画/过渡表现得很奇怪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在SwiftUI中有一个ScrollView,其中包含多个元素,其中一些元素可以在点击时扩展.

I have a ScrollView in SwiftUI with multiple elements, some of them expands on tap.

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")
        }
    }
}

如果尝试打开其中一个扩展文本,您会看到过渡不平滑,有点像跳跃,然后过渡开始.

If you try to open one of the expanding texts, you will see that the transition is not smooth, it kind of like jumps and then the transition starts.

https://media.giphy.com/media/cjhClEVwgsEQpkBGAv/giphy.gif

这就是我尝试过的:

  • 例如,如果我删除滚动视图并将其放置到VStack中,它将运行良好,但这不是一个选择,因为我有更多的元素无法显示在屏幕上.
  • 我已尝试为滚动视图设置动画,因为我读到它解决了此类问题,如下所示:
ScrollView {
            ExpandingView()
            ExpandingView()
            ExpandingView()
            Text("Some static text")
        }.animation(.spring())

就打开过渡而言,它工作得很好,使用弹簧效果甚至看起来更好,但是整个滚动视图的弹簧动画会在视图出现时播放,这是我所不希望的.

It works fine in terms of the opening transition, it even looks better with the spring effect, but the spring animation for the whole scrollview plays when the view appears, which I don't want.

https://media.giphy.com/media/lTMG9mGD0X0qrksYtB/giphy.gif

同样,如果我将ScrollView更改为VStack,则动画不会在出现时播放,这很好,但是我必须使用scrollview.因此,对我来说最好的解决方案是保留动画以打开文本,但是在视图出现时以某种方式将其删除.

Again, if I change the ScrollView to a VStack, the animation does not play on appearing which is nice, but I have to use a scrollview. So the best solution for me would be to keep the animation for opening the texts, but somehow remove it when the view appears.

推荐答案

这里是可能的解决方案.另请阅读内联注释.经过Xcode 11.4/iSO 13.4的测试

Here is possible solution. Read also comments inline. Tested with 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
            }
        }
    }
}

这篇关于在scrollview中的SwiftUI动画/过渡表现得很奇怪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆