Viv*_*ive 54 ios swift swiftui
使用以下代码:
struct HomeView: View {
var body: some View {
NavigationView {
List(dataTypes) { dataType in
NavigationLink(destination: AnotherView()) {
HomeViewRow(dataType: dataType)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,当HomeView出现时,NavigationLink立即加载AnotherView. 结果,所有AnotherView依赖项也被加载,即使它在屏幕上还不可见。用户必须单击该行才能使其出现。MyAnotherView包含一个DataSource,在那里发生各种事情。问题是此时DataSource已加载整体,包括一些计时器等。
难道我做错了什么..?如何以这种方式处理它,AnotherView一旦用户按下它就会加载HomeViewRow?
Mwc*_*Mac 86
我发现解决这个问题的最好方法是使用惰性视图。
struct NavigationLazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
Run Code Online (Sandbox Code Playgroud)
然后 NavigationLink 将如下所示。您可以将要显示的视图放在里面()
NavigationLink(destination: NavigationLazyView(DetailView(data: DataModel))) { Text("Item") }
Run Code Online (Sandbox Code Playgroud)
编辑:请参阅@MwcsMac 的答案以获得更简洁的解决方案,该解决方案将视图创建包装在一个闭包中,并且仅在视图呈现后才对其进行初始化。
ForEach由于函数构建器确实必须评估表达式,因此需要自定义来执行您的要求
NavigationLink(destination: AnotherView()) {
HomeViewRow(dataType: dataType)
}
Run Code Online (Sandbox Code Playgroud)
为了能够显示每个可见行HomeViewRow(dataType:),在这种情况下也AnotherView()必须初始化。
所以为了避免这种情况,一个习惯ForEach是必要的。
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)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11323 次 |
| 最近记录: |