[英]Preselecting a (dynamic) item in NavigationSplitView
I'm using NavigationSplitView
to structure the user interface of my (macOS) app like this:我正在使用NavigationSplitView
来构建我的 (macOS) 应用程序的用户界面,如下所示:
struct NavigationView: View {
@State private var selectedApplication: Application?
var body: some View {
NavigationSplitView {
ApplicationsView(selectedApplication: $selectedApplication)
} detail: {
Text(selectedApplication?.name ?? "Nothing selected")
}
}
}
The sidebar is implemented using ApplicationsView
that looks like this:侧边栏是使用如下所示的ApplicationsView
实现的:
struct ApplicationsView: View {
@FetchRequest(fetchRequest: Application.all()) private var applications
@Binding var selectedApplication: Application?
var body: some View {
List(applications, selection: $selectedApplication) { application in
NavigationLink(value: application) {
Text(application.name)
}
}
// This works, but looks a bit complicated and... ugly
.onReceive(applications.publisher) { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
if selectedApplication == nil {
selectedApplication = applications.first
}
}
}
// This also does not work, as the data is not yet available
.onAppear {
selectedApplication = applications.first
}
}
}
I'm currently preselecting the first Application
item (if it exists) using the shown onReceive
code, but it looks complicated and a bit ugly.我目前正在使用显示的onReceive
代码预选第一个Application
项(如果它存在),但它看起来很复杂而且有点难看。 For example, it only works properly when delaying the selection code.例如,它只有在延迟选择代码时才能正常工作。
Is there a better way to achieve this?有没有更好的方法来实现这一目标?
Thanks.谢谢。
How about just setting the selectedApplication
using the task
modifier with an id
as follows:如何使用带有id
的task
修饰符设置selectedApplication
如下:
struct ApplicationsView: View {
@FetchRequest(fetchRequest: Application.all()) private var applications
@Binding var selectedApplication: Application?
var body: some View {
List(applications, selection: $selectedApplication) { application in
NavigationLink(value: application) {
Text(application.name!)
}
}
.task(id: applications.first) {
selectedApplication = applications.first
}
}
}
the task is fired when the view is first displayed, and when the id object is updated, so this works without introducing a delay首次显示视图时会触发任务,并且更新 id object 时会触发该任务,因此可以在不引入延迟的情况下工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.