Ios self.shouldShowDestination=true } } } //马克:二等兵 @国家私有var shouldShowDestination=false }
并将其作为Ios self.shouldShowDestination=true } } } //马克:二等兵 @国家私有var shouldShowDestination=false },ios,swift,swiftui,Ios,Swift,Swiftui,并将其作为表单(或列表)的一部分重复使用: 表单{ FormNavigationRow(标题:“一”,目的地:文本(“1”)) FormNavigationRow(标题:“两个”,目的地:文本(“2”)) FormNavigationRow(标题:“三”,目的地:文本(“3”)) } 在destination(目的地)视图中,您应该收听Appear(附件)上的事件,并将仅当新屏幕出现时才需要执行的所有代码放在那里。像这样: struct DestinationView:View{ var bod
表单
(或列表
)的一部分重复使用:
表单{
FormNavigationRow(标题:“一”,目的地:文本(“1”))
FormNavigationRow(标题:“两个”,目的地:文本(“2”))
FormNavigationRow(标题:“三”,目的地:文本(“3”))
}
在destination(目的地)视图中,您应该收听Appear(附件)上的事件,并将仅当新屏幕出现时才需要执行的所有代码放在那里。像这样:
struct DestinationView:View{
var body:一些观点{
文本(“你好,世界!”)
奥纳佩尔先生{
//在这里做一些重要的事情,比如从RESTAPI获取数据
//此代码仅在视图出现时执行
}
}
}
噢,这太可怕了,它会对体系结构产生影响。希望他们能在发布前修复它。是的,从优化的角度来看,这并不好,但实际上它工作正常。我将从API端点异步加载数据发生在appear上,如果我点击一个单元格并加载另一个视图控制器,我就会这样做。我会加载视图,然后加载所有相关的远程内容。在这一点上唯一的区别是,它在用户点击单元之前加载脚手架。不知道这是一个优化还是意外的结果,他们还没有完成最终的解决方案。您正在测试视图何时加载,而不是何时初始化。请将init(i:Int){self.i=i print(“test”)}
粘贴到您的另一个视图中,您将看到它在HomeView列表单元格加载中被调用。啊,我明白了,这通常是通过.onAppear
完成的。我发布了一个如何惰性地初始化另一个视图的例子。我认为初始化应该在它实际打开后进行。从逻辑的角度看:你有一张1000个位置的桌子。在NavigationLink上,可以将视图链接到地图和视频播放器。立即启动18项。现在使用非可选的let是很愉快的,所以您可以这样做。所以你把所有的项目都放在那里。协调器模式也会很奇怪。它应该同样适用于UITableViewCell-它在显示单元格时初始化单元格,并且仅在按下该单元格时执行操作。优化,我明白你的意思。但是请注意,据我所知,此解决方案既不重用旧视图,也不关心多次创建视图,从而导致每次切换到视图时再次构建视图。您是说UITableViewCell?这将使它们退出队列,从而100%重用旧单元。这解决了我所有嵌套视图模型(及其存储库的api调用)过早初始化的问题。谢谢!我觉得很奇怪,这不是NavigationLink的默认行为。它给我带来了很多问题@MwcsMac没有多少次我想亲吻回答这个问题的人。谢谢我不太明白为什么这不是默认的行为,但是,我想知道是否会有一个解决方案,这将意味着这拆封将不会有一天是必要的。伟大的解决方案!为了方便起见,我如何将其包装为LazyNavigationLink
?例如,只需调用LazyNavigationLink(DetailView(数据:…
)这种非延迟加载细节视图的方式似乎很疯狂。非常不直观。加载视图后,ViewDidLoad只调用一次。但是ViewDidLoad会出现(类似于SwiftUI中的onAppear)每次显示视图时都会调用。因此,在下载的情况下,您通常希望在viewDidLoad上执行此操作,而不是在onAppear
上执行此操作。后一种情况可能会经常发生。
struct HomeView: View {
var body: some View {
NavigationView {
List(dataTypes) { dataType in
NavigationLink(destination: AnotherView()) {
HomeViewRow(dataType: dataType)
}
}
}
}
}
NavigationLink(destination: AnotherView()) {
HomeViewRow(dataType: dataType)
}
import SwiftUI
struct LoadLaterView: View {
var body: some View {
HomeView()
}
}
struct DataType: Identifiable {
let id = UUID()
var i: Int
}
struct ForEachLazyNavigationLink<Data: RandomAccessCollection, Content: View, Destination: View>: View where Data.Element: Identifiable {
var data: Data
var destination: (Data.Element) -> (Destination)
var content: (Data.Element) -> (Content)
@State var selected: Data.Element? = nil
@State var active: Bool = false
var body: some View {
VStack{
NavigationLink(destination: {
VStack{
if self.selected != nil {
self.destination(self.selected!)
} else {
EmptyView()
}
}
}(), isActive: $active){
Text("Hidden navigation link")
.background(Color.orange)
.hidden()
}
List{
ForEach(data) { (element: Data.Element) in
Button(action: {
self.selected = element
self.active = true
}) { self.content(element) }
}
}
}
}
}
struct HomeView: View {
@State var dataTypes: [DataType] = {
return (0...99).map{
return DataType(i: $0)
}
}()
var body: some View {
NavigationView{
ForEachLazyNavigationLink(data: dataTypes, destination: {
return AnotherView(i: $0.i)
}, content: {
return HomeViewRow(dataType: $0)
})
}
}
}
struct HomeViewRow: View {
var dataType: DataType
var body: some View {
Text("Home View \(dataType.i)")
}
}
struct AnotherView: View {
init(i: Int) {
print("Init AnotherView \(i.description)")
self.i = i
}
var i: Int
var body: some View {
print("Loading AnotherView \(i.description)")
return Text("hello \(i.description)").onAppear {
print("onAppear AnotherView \(self.i.description)")
}
}
}
struct AnotherView: View {
var body: some View {
VStack{
Text("Hello World!")
}.onAppear {
print("I only printed when the view appeared")
// trigger whatever you need to here instead of on init
}
}
}
struct NavigationLazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
NavigationLink(destination: NavigationLazyView(DetailView(data: DataModel))) { Text("Item") }