Programmatic Navigation using SwiftUI| 使用 SwiftUI 进行程序化导航
If you’re new to iOS development and have just started working with SwiftUI you may know NavigationLink
as the way you are able to transition between different views in your app. What may be immediately less apparent is how you can do this programmatically.
For instance, if you made a login screen and the user presses a Login
button — you may want to transition to the home screen of your application if the login success and display a pop-up if this fails. This is where programmatic navigation would come in.
If you’ve used UIKit in the past you will know about performSegue
and pushViewController
which are both ways to transition to a new view with code. With SwiftUI you cannot just call a function and have a new view pop up. You are going to have to use NavigationLink
, a type of view in SwiftUI
, to accomplish this.
Using NavigationLink to accomplish programmatic navigation
With SwiftUI comes the new @State
property wrapper. The official Apple documentation does a pretty good job explaining how @State
works. In essence, @State
wraps your properties and whenever the value of the property changes “the view invalidates its appearance and recomputes the body.” You can think of it as the “trigger” for the navigation to occur.
A NavigationLink
is a SwiftUI button that will trigger navigation to another view when tapped. When it is tapped, the transition to the new view happens instantly. Since we may want to perform some functionality before transitioning to a new view (logging a user in, downloading some JSON data, etc.) we are going to use the isActive
part of the constructor to get programmatic transition functionality.
We are going to use @State
in combination with NavigationLink
to get programmatic navigation in SwiftUI.
If you are following along from scratch, create a new SwiftUI view and do all of the following in that struct.
Declare a @State
property in your struct initialized to false
(in the case of a Bool
).
Create a NavigationLink
and add it to the body of the view like so:
We set “isActive” equal to our state so the view will recompile when our state become true, and since it is true the NavigationLink will trigger.
The reason we want to put an EmptyView
inside the NavigationLink
is because the NavigationLink
is not really a visual part of our UI. It just provides some under-the-hood functionality to our onscreen buttons. If you were to put something besides an EmptyView
in there you would get a useless button on the screen — and nobody wants that!
Where in the above code snippet NewView()
is the view you want to transition to. And the property you declared as @State
is a Bool
named action.
When you want to programmatically transition to your new view, you simply set action = true
. And as the Apple documentation states, your view will recompute its body; since you set your state to true it will also go to the destination of your NavigationLink
.
In the completed code below, for example, I called a function clicked()
whenever a Text
was tapped which set my state to true
.
If you’ve done all the above and it’s still not working, you may want to make sure that your root view, or the view you are currently working with, has a NavigationView { }
encapsulating everything in said View
. If you don’t have that NavigationView
somewhere in the view hierarchy whenever you try to trigger your navigation nothing will happen. Your state will just be set to true
and the NavigationLink
will do nothing.
Conclusion
Putting it all together you should have a basic view that looks something like this:
The use of HStack is because we are embedding multiples views in there, the NavigationLink will not show up on the screen since it is an EmptyView.
origin link: https://medium.com/swift2go/programmatic-navigation-using-swiftui-a0dfdad9b5fe
google translate如下
------------------------------------------------------------------------------------------------------------
如果您是iOS开发的新手,并且刚刚开始使用SwiftUI,您可能会知道您可以NavigationLink
在应用程序中的不同视图之间进行转换。可能现在不太明显的是如何以编程方式执行此操作。
例如,如果您创建了一个登录屏幕,而用户按下了一个Login
按钮,那么,如果登录成功,则可能需要转换到应用程序的主屏幕,如果登录失败,则显示一个弹出窗口。这就是程序化导航的地方。
如果您过去曾经使用过UIKit,那么您将了解performSegue
以及pushViewController
有两种方法可以使用代码过渡到新视图。使用SwiftUI,您不仅可以调用一个函数并弹出一个新视图。您将必须使用NavigationLink
中的一种视图SwiftUI
来完成此任务。
使用NavigationLink完成编程导航
随着SwiftUI而来的新@State
属性包装。Apple的官方文档在解释@State
工作原理方面做得很好。本质上,@State
包装您的属性,并且只要属性的值发生变化,“视图就会使外观无效并重新计算主体。” 您可以将其视为导航发生的“触发器”。
ANavigationLink
是一个SwiftUI按钮,点击该按钮将触发导航到另一个视图。轻按一下,便会立即过渡到新视图。由于我们可能想在过渡到新视图(登录用户,下载一些JSON数据等)之前执行一些功能,因此我们将使用isActive
构造函数的一部分来获取程序化过渡功能。
我们将与@State
结合使用NavigationLink
以在SwiftUI中获得程序化导航。
如果您从头开始,请创建一个新的SwiftUI视图,并在该结构中执行以下所有操作。
@State
在您的结构中声明一个初始化为的属性false
(对于Bool
)。
创建一个NavigationLink
并将其添加到视图主体中,如下所示:
我们将“ isActive”设置为等于我们的状态,以便当我们的状态为true时视图将重新编译,并且由于为true,NavigationLink将触发。
我们之所以要放在EmptyView
其中NavigationLink
是因为,NavigationLink
它实际上并不是UI的可视部分。它只是为我们的屏幕按钮提供了一些后台功能。如果您要EmptyView
在其中放置其他内容,则屏幕上会出现一个无用的按钮-没人想要!
上面代码片段NewView()
中要转换到的视图。并且您声明为的属性@State
是Bool
命名操作。
要以编程方式过渡到新视图时,只需设置action = true
。正如Apple文档所述,您的视图将重新计算其主体。由于您将状态设置为true,因此它也将转到您的目的地NavigationLink
。
例如,在下面的完整代码中,clicked()
每当Text
点击a时,我都会调用一个函数,将状态设置为true
。
如果您已完成上述所有操作,但仍无法使用,则可能要确保您的根视图或当前正在使用的视图NavigationView { }
将所有内容封装在said中View
。如果NavigationView
每次尝试触发导航时,视图层次结构中都没有该位置,则不会发生任何事情。您的状态将被设置为,true
并且将NavigationLink
不会执行任何操作。
结论
放在一起,您应该拥有一个看起来像这样的基本视图:
HStack的使用是因为我们在其中嵌入了多个视图,因为NavigationLink是EmptyView,所以它不会显示在屏幕上。
版权声明: 本文为 InfoQ 作者【Daniel】的原创文章。
原文链接:【http://xie.infoq.cn/article/6decbd9d9d4845b18756ec6bc】。文章转载请联系作者。
评论