Swift 视图之间的GeometryReader转换最初会导致一个外观触发器
我一直在从事Swiftui1.0中的一个项目,因为它需要对iOS13.0设备的支持(因此没有可用的Swift 视图之间的GeometryReader转换最初会导致一个外观触发器,swift,user-interface,swiftui,transition,geometryreader,Swift,User Interface,Swiftui,Transition,Geometryreader,我一直在从事Swiftui1.0中的一个项目,因为它需要对iOS13.0设备的支持(因此没有可用的fullScreenCover)。我要求我的应用程序在视图之间有清晰的过渡动画,因此我在整个应用程序中广泛使用GeometryReader,如下所示: Login appeared! Two appeared! Fetch data... One appeared! Fetch data... 现在我已经完成了80%的UI,我正在尝试集成数据获取部分。因此,我所做的是在视图上调用我的onAppe
fullScreenCover
)。我要求我的应用程序在视图之间有清晰的过渡动画,因此我在整个应用程序中广泛使用GeometryReader
,如下所示:
Login appeared!
Two appeared! Fetch data...
One appeared! Fetch data...
现在我已经完成了80%的UI,我正在尝试集成数据获取部分。因此,我所做的是在视图上调用我的onAppear
方法中的数据获取方法。这是我的密码:
struct ContentView: View {
@State private var isUserLoggedIn = false
var body: some View {
GeometryReader { geometry in
HomeView()
LoginView(isUserLoggedIn: $isUserLoggedIn)
.offset(y: isUserLoggedIn ? geometry.size.height + geometry.safeAreaInsets.bottom : 0)
}
}
}
struct LoginView: View {
@Binding var isUserLoggedIn: Bool
var body: some View {
Button("Login") {
withAnimation {
isUserLoggedIn.toggle()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.red)
.edgesIgnoringSafeArea(.all)
.onAppear {
print("Login appeared!")
}
}
}
struct HomeView: View {
@State private var isTwoSelected = false
var body: some View {
GeometryReader { geometry in
OneView(isTwoSelected: $isTwoSelected)
.offset(x: isTwoSelected ? -geometry.size.width : 0)
TwoView(isTwoSelected: $isTwoSelected)
.offset(x: isTwoSelected ? 0 : geometry.size.width)
}
}
}
struct OneView: View {
@Binding var isTwoSelected: Bool
var body: some View {
NavigationView {
Button("Goto Two") {
withAnimation {
isTwoSelected.toggle()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.green)
.edgesIgnoringSafeArea(.all)
.navigationBarTitle(Text("One"))
.onAppear {
print("One appeared! Fetch data...")
}
}
}
}
struct TwoView: View {
@Binding var isTwoSelected: Bool
var body: some View {
NavigationView {
Button("Goto One") {
withAnimation {
isTwoSelected.toggle()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.yellow)
.edgesIgnoringSafeArea(.all)
.navigationBarTitle(Text("Two"))
.onAppear {
print("Two appeared! Fetch data...")
}
}
}
}
但我现在面临的问题是,它们是同时触发的。您可以看到控制台打印如下:
Login appeared!
Two appeared! Fetch data...
One appeared! Fetch data...
只有当数据出现在设备的视图框中时,我如何才能将数据提取到相应的视图中?有关提取的问题已解决!看到代码,我可以更新动画或其他小东西!这对您来说只是快速编码。
正如@Asperi在评论中所述,
转换
似乎是正确的方法,而不是偏移
。下面是带有转换的实现(仅添加已更改的视图):
最初显示屏幕外偏移的视图并不意味着它不显示。相反,您需要使用基于.transition
的方法,在这种情况下,视图确实出现/消失了。例如,在这里,see或@Asperitransition
似乎是正确的方法。虽然在组合子视图的转换时,父视图转换似乎处于非活动状态(登录到主视图)。有办法解决这个问题吗?我已经添加了过渡方法,正如您在下面所述。不编译:onChange
仅在iOS 14.0
上可用。另外,UIScreen.main.bounds
在SwiftUI
中使用不受欢迎。检查问题,它清楚地说明解决方案必须适用于iOS 13.0
。哪些代码部分对您不可用?我可以为iOS编辑它们13@Omid您可以使用onReceive
而不是onChange
和GeometryReader
而不是UIScreen.main.bounds
@pawello2222,我想他已经找到了答案!主要关注的是如何在一个视图中获取所有视图,我解决了这个问题,无论他希望iOS 13如何。
struct ContentView: View {
@State private var isUserLoggedIn = false
var body: some View {
if isUserLoggedIn {
HomeView()
.transition(.asymmetric(insertion: .move(edge: .top), removal: .move(edge: .bottom)))
} else {
LoginView(isUserLoggedIn: $isUserLoggedIn)
.transition(.asymmetric(insertion: .move(edge: .top), removal: .move(edge: .bottom)))
}
}
}
struct HomeView: View {
@State private var isTwoSelected = false
var body: some View {
Group {
if !isTwoSelected {
OneView(isTwoSelected: $isTwoSelected)
.transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)))
} else {
TwoView(isTwoSelected: $isTwoSelected)
.transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
}
}
}
}