在SwiftUI中使用分段样式选择器在两个页面之间滑动

问题描述 投票:0回答:3

我有一个Picker.pickerStyle(SegmentedPickerStyle()),使其成为分段控件。我想使页面在它们之间平滑滑动,而不是使用条件语句替换视图。

这里是我到目前为止所做的事情的gif:

What I have made

这里是到目前为止的代码(由if控制,而不是在不同页面之间切换:]

struct AuthView: View {

    @State private var authPath = 0

    /* ... */

    var body: some View {
        VStack {
            Picker(selection: $authPath, label: Text("Authentication Path")) {
                Text("Log In").tag(0)
                Text("Sign Up").tag(1)
            }
            .pickerStyle(SegmentedPickerStyle())

            Spacer()

            if authPath == 0 {
                LogInView(/* ... */)
            } else {
                SignUpView(/* ... */)
            }

            Spacer()
        }
        .padding()
        .background(Color("Color.Background").edgesIgnoringSafeArea(.all))
    }
}

我想要类似于UIPageViewController的内容。如果有SwiftUI版本或一个不错的替代版本,那确实有帮助。

但是,如果我确实需要使用UIPageViewController求助于UIKit,我不知道如何使用SwiftUI来实现它。

ios swift swiftui uipageviewcontroller uiviewrepresentable
3个回答
0
投票

您可以将UIViewRepresentableLoginView包装在某个容器中以使其具有动画效果。

SignupView

0
投票

这里是一种可能的方法(请注意,由于Preview无法正确处理 var body: some View { VStack { Picker(selection: $authPath, label: Text("Authentication Path")) { // withAnimation(Animation.easeInOut.speed(0.5)){ Text("Log In").tag(0) Text("Sign Up").tag(1)} //} .pickerStyle(SegmentedPickerStyle()) Spacer() if authPath == 0 { NavigationView{ Text("1") }.animation(.default).transition(.move(edge: .leading)) //(/* ... */) } else { NavigationView{ Text("2") }.animation(.default).transition(.move(edge: .leading)) //(/* ... */) } Spacer() } .padding() .background(Color("Color.Background").edgesIgnoringSafeArea(.all)) } 转换,因此需要使用模拟器进行测试)

演示(仅使用了存根视图,可以配置动画和过渡的参数,但是思想保持不变)。

注意:过渡视图的背景应该是不透明的(在此使用.move,否则过渡看起来...不好。

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS84Y0ZNMC5naWYifQ==” alt =“ SwiftUI移动视图过渡”>

Color.white

0
投票

这些其他答案为我指明了正确的方向,但是代码似乎有些冗长或无法按预期运行。

为了使我的工作正常,这里发生了什么变化:

  • 将填充添加到struct TestTwoViewMoveIn: View { @State private var authPath: Int? = nil /* ... */ var body: some View { VStack { Picker(selection: Binding<Int>( get: { self.authPath ?? 0 }, set: { tag in withAnimation { // needed explicit for transitions self.authPath = tag } }), label: Text("Authentication Path")) { Text("Log In").tag(0) Text("Sign Up").tag(1) } .pickerStyle(SegmentedPickerStyle()) Spacer() ZStack { Rectangle().fill(Color.clear) if nil == authPath { LogInView(/* ... */) .background(Color.white) // << set your background } if authPath == 0 { LogInView(/* ... */) .background(Color.white) // << set your background .transition(.move(edge: .leading)) } if authPath == 1 { SignUpView(/* ... */) .background(Color.white) // << set your background .transition(.move(edge: .trailing)) } } Spacer() } .padding() .background(Color("Color.Background").edgesIgnoringSafeArea(.all)) } }
  • Picker的末尾删除了填充。
  • VStack更改为2if-elses。
  • ifanimation中的每一个添加了transitionpaddingLogInView修饰符。

原件:

SignInView

新:

struct AuthView: View {

    @State private var authPath = 0

    /* ... */

    var body: some View {
        VStack {
            Picker(selection: $authPath, label: Text("Authentication Path")) {
                Text("Log In").tag(0)
                Text("Sign Up").tag(1)
            }
            .pickerStyle(SegmentedPickerStyle())

            Spacer()

            if authPath == 0 {
                LogInView(/* ... */)
            } else {
                SignUpView(/* ... */)
            }

            Spacer()
        }
        .padding()
        .background(Color("Color.Background").edgesIgnoringSafeArea(.all))
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.