[英]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.