Yury
Yury

Reputation: 347

How to animate view appearance?

I have a custom view. It used as a cell in a List view. I would like to animate appearance of a Group subview on quote.expanded = true (e.g. fading).

.animation(.default) modifier does not work.

struct QuoteView: View {

    var quote : QuoteDataModel

    var body: some View {
        VStack(alignment: .leading, spacing: 5) {
            Text(quote.latin)
                .font(.title)
            if quote.expanded {
                Group() {
                    Divider()
                    Text(quote.russian).font(.body)
                }
            }
        }
    }
}

Upvotes: 0

Views: 3510

Answers (3)

Chris
Chris

Reputation: 8091

try this....but you will see, that there are still other problems, because the text is left aligned...

var body: some View {

    VStack(alignment: .leading, spacing: 5) {
        Button("Tap me") {
            withAnimation() {

                self.expanded.toggle()
                if self.expanded {
                    self.opacity = 1
                } else {
                    self.opacity = 0
                }
            }

        }
        Text("aha")
            .font(.title)
        if expanded {
            Group() {
                Divider()
                Text("oho").font(.body)
            }.opacity(opacity)
        }
    }
}

Upvotes: 0

John M.
John M.

Reputation: 9463

The following code animates for me. Note that animation inside a list, while still probably better than no animation, can still look kind of weird. This is because the height of the list rows themselves do not animate, and snap to their final height, while the view inside the row does animate. This is a SwiftUI issue, and there's not anything you can do about it for now other than file feedback that this behavior doesn't look great.

struct StackOverflowTests: View {
    @State private var array = [QuoteDataModel(), QuoteDataModel(), QuoteDataModel()]

    var body: some View {
        List {
            ForEach(array.indices, id: \.self) { index in
                QuoteView(quote: self.array[index])
                    .onTapGesture { self.array[index].expanded.toggle() }
            }
        }
    }
}

struct QuoteView: View {

    var quote : QuoteDataModel

    var body: some View {
        VStack(alignment: .leading, spacing: 5) {
            Text(quote.latin)
                .font(.title)
            if quote.expanded {
                Group() {
                    Divider()
                    Text(quote.russian).font(.body)
                }
            }
        }
        .animation(.default)
    }
}

Upvotes: 1

Related Questions