簡體   English   中英

帶有過渡的 SwiftUI 動畫始終顯示幻燈片動畫

[英]SwiftUI animation with transition always show slide animation

我在 Listview 中有子導航並嘗試實現 leftSlide 和 rightSlide 動畫,但它始終顯示默認幻燈片動畫。 我什至嘗試添加.transition(.move(edge: . leading)) & .transition(.move(edge: . trailing))

import SwiftUI
import Combine

struct GameTabView: View {
    @State var selectedTab: Int = 0

    init() {
        UITableView.appearance().sectionHeaderTopPadding = 0
    }

    var body: some View {
        listView
            .ignoresSafeArea()
    }

    var listView: some View {
        List {
            Group {
                Color.gray.frame(height: 400)
                sectionView
            }
            .listRowInsets(EdgeInsets())
        }
        .listStyle(.plain)
    }
    var sectionView: some View {
        Section {
            tabContentView
                .transition(.move(edge: . leading)) // NOT WORKING
                .background(Color.blue)
        } header: {
            headerView
        }
    }

    private var headerView: some View {
        ScrollViewReader { proxy in
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 16) {
                    Button {
                        withAnimation {
                            selectedTab = 0
                        }
                    } label: {
                        Text("AAAA")
                            .padding()
                    }
                    Button {
                        withAnimation {
                            selectedTab = 1
                        }
                    } label: {
                        Text("BBBB")
                            .padding()
                    }
                    Button {
                        withAnimation {
                            selectedTab = 2
                        }
                    } label: {
                        Text("BBBB")
                            .padding()
                    }
                }
            }
        }
        .background(Color.green)
    }

    @ViewBuilder private var tabContentView: some View {
        switch selectedTab {
        case 0:
            DummyScreen(title: "FIRST", color: .red)
        case 1:
            DummyScreen(title: "SECOND", color: .green)
        case 2:
            DummyScreen(title: "THIRD", color: .blue)
        default:
            EmptyView()
        }
    }
}

struct DummyScreen: View {
    let title: String
    let color: Color
    var body: some View {
        VStack {
            ForEach(0..<15, id: \.self) { index in
                HStack {
                    Text("#\(index): title \(title)")
                        .foregroundColor(Color.black)
                        .font(.system(size: 30))
                        .padding(.vertical, 20)
                    Spacer()
                }
                .background(Color.yellow)
            }
        }
        .background(color)
    }
}

在此處輸入圖像描述

正如 Asperi 所說,您可以更改為另一種類型的 View 以使過渡生效。

我嘗試了您的代碼,將 List 更改為 VStack,其中帶有 ScrollView 以環繞 tabContentView,UI 的結果顯示相同,除了現在有適當的動畫,並且您不必手動調整內容的高度,因為 HStack高度是根據您的 Text() 增長而動態變化的。

編輯:標題固定,動畫固定

import SwiftUI
import SwiftUITrackableScrollView //Added
import Combine

struct GameTabView: View {

@State private var scrollViewContentOffset = CGFloat(0) //Added
@State var selectedTab: Int = 0

init() {
    UITableView.appearance().sectionHeaderTopPadding = 0
}

var body: some View {
    listView
        .ignoresSafeArea()
}

var listView: some View {
    ZStack { //Added
        TrackableScrollView(.vertical, showIndicators: true, contentOffset: $scrollViewContentOffset)  {
            VStack {
                Color.gray.frame(height: 400)
                sectionView
            }
        }
        if(scrollViewContentOffset > 400) {
            VStack {
                headerView
                Spacer()
            }
        }
    }
}

var sectionView: some View {
    Section {
        tabContentView
            .transition(.scale) // FIXED
            .background(Color.blue)
    } header: {
        headerView
    }
}

private var headerView: some View {
    ScrollViewReader { proxy in
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 16) {
                Button {
                    withAnimation {
                        selectedTab = 0
                    }
                } label: {
                    Text("AAAA")
                        .padding()
                }
                Button {
                    withAnimation {
                        selectedTab = 1
                    }
                } label: {
                    Text("BBBB")
                        .padding()
                }
                Button {
                    withAnimation {
                        selectedTab = 2
                    }
                } label: {
                    Text("BBBB")
                        .padding()
                }
            }
        }
    }
    .background(Color.green)
}

@ViewBuilder private var tabContentView: some View {
    switch selectedTab {
    case 0:
        DummyScreen(title: "FIRST", color: .red)
    case 1:
        DummyScreen(title: "SECOND", color: .green)
    case 2:
        DummyScreen(title: "THIRD", color: .blue)
    default:
        EmptyView()
    }
}
}

struct DummyScreen: View {
let title: String
let color: Color
var body: some View {
    VStack {
        ForEach(0..<15, id: \.self) { index in
            HStack {
                Text("#\(index): title \(title)")
                    .foregroundColor(Color.black)
                    .font(.system(size: 30))
                    .padding(.vertical, 20)
                Spacer()
            }
            .background(Color.yellow)
        }
    }
    .background(color)
}
}

感謝@tail 和@Asperi

我終於通過使用ScrollviewProxy更新ScrollView得到了解決方案:

import SwiftUI
import Combine

struct GameTabView: View {
    @State var selectedTab: Int = 0
    @State var proxy: ScrollViewProxy?

    init() {
        UITableView.appearance().sectionHeaderTopPadding = 0
    }

    var body: some View {
        listView
            .ignoresSafeArea()
    }

    var listView: some View {
        List {
            Group {
                Color.gray.frame(height: 400)
                sectionView
            }
            .listRowInsets(EdgeInsets())
        }
        .listStyle(.plain)
    }
    var sectionView: some View {
        Section {
            tabContentView
        } header: {
            headerView
        }
    }

    private var headerView: some View {
        ScrollViewReader { proxy in
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 16) {
                    Button {
                        withAnimation {
                            selectedTab = 0
                            self.proxy?.scrollTo(0, anchor: .center)
                        }
                    } label: {
                        Text("AAAA")
                            .padding()
                    }
                    Button {
                        withAnimation {
                            selectedTab = 1
                            self.proxy?.scrollTo(1, anchor: .center)
                        }
                    } label: {
                        Text("BBBB")
                            .padding()
                    }
                    Button {
                        withAnimation {
                            selectedTab = 2
                            self.proxy?.scrollTo(2, anchor: .center)
                        }
                    } label: {
                        Text("BBBB")
                            .padding()
                    }
                }
            }
        }
        .background(Color.green)
    }

    @ViewBuilder private var tabContentView: some View {
        ScrollViewReader { proxy in
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 0) {
                    ForEach(0..<3, id: \.self) { i in
                        DummyScreen(title: "Name: \(i)", color: .blue)
                            .frame(idealWidth: UIScreen.main.bounds.width)
                            .id(i)
                    }
                }
            }
            .onAppear {
                self.proxy = proxy
            }
        }
    }
}

暫無
暫無

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

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