我有一个带有基本列表/详细信息结构的 SwiftUI 应用程序。从模态表创建一个新项目。当我创建一个新项目并保存它时,我希望选择该列表项。实际上,如果在添加之前没有选择任何项目,则在添加之后不会选择任何项目。如果在添加之前选择了一个项目,则在添加之后选择了相同的项目。
我将包含 ContentView 的代码,但这确实是 List/Detail 的最简单示例。
struct ContentView: View {
@ObservedObject var resortStore = ResortStore()
@State private var addNewResort = false
@State private var coverDeletedDetail = false
@Environment(\.presentationMode) var presentationMode
var body: some View {
List {
ForEach(resortStore.resorts) { resort in
NavigationLink(destination: ResortView(resort: resort)) {
HStack(spacing: 20) {
Image("FlatheadLake1")
//bunch of modifiers
VStack(alignment: .leading, spacing: 10) {
//the cell contents
}
}
}
}
.onDelete { indexSet in
self.removeItems(at: [indexSet.first!])
self.coverDeletedDetail.toggle()
}
if UIDevice.current.userInterfaceIdiom == .pad {
NavigationLink(destination: WelcomeView(), isActive: self.$coverDeletedDetail) {
Text("")
}
}
}//list
.onAppear(perform: self.selectARow)
.navigationBarTitle("Resorts")
.navigationBarItems(leading:
//buttons
}//body
func removeItems(at offsets: IndexSet) {
resortStore.resorts.remove(atOffsets: offsets)
}
func selectARow() {
//nothing that I have tried works here
print("selectARow")
}
}//struct
Run Code Online (Sandbox Code Playgroud)
再次 - 添加项目模式是非常基本的:
struct AddNewResort: View {
//bunch of properties
var body: some View {
VStack {
Text("Add a Resort")
VStack {
TextField("Enter a name", text: $resortName)
//the rest of the fields
}
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(EdgeInsets(top: 20, leading: 30, bottom: 20, trailing: 30))
Button(action: {
let newResort = Resort(id: UUID(), name: self.resortName, country: self.resortCountry, description: self.resortDescription, imageCredit: "Credit", price: Int(self.resortPriceString) ?? 0, size: Int(self.resortSizeString) ?? 0, snowDepth: 20, elevation: 3000, runs: 40, facilities: ["bar", "garage"])
self.resortStore.resorts.append(newResort)
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Save Trip")
}
.padding(.trailing, 20)
}
}
}
Run Code Online (Sandbox Code Playgroud)
显示问题 - 带有选择的列表:
创建新项目后的列表显示了先前的选择:
任何指导将不胜感激。Xcode 11.4
小智 5
我尝试尽可能地重构您的代码,以便它能够构建。这就是我最终得到的。我们有一个度假村列表,当新度假村保存在 AddNewResort 工作表中时,如果我们当前处于拆分视图(horizontalSizeClass 为常规),我们将选择新度假村,否则只需关闭该工作表。
import SwiftUI
class ResortStore: ObservableObject {
@Published var resorts = [Resort(id: UUID(), name: "Resort 1")]
}
struct ContentView: View {
@ObservedObject var resortStore = ResortStore()
@State private var addingNewResort = false
@State var selectedResortId: UUID? = nil
var navigationLink: NavigationLink<EmptyView, ResortView>? {
guard let selectedResortId = selectedResortId,
let selectedResort = resortStore.resorts.first(where: {$0.id == selectedResortId}) else {
return nil
}
return NavigationLink(
destination: ResortView(resort: selectedResort),
tag: selectedResortId,
selection: $selectedResortId
) {
EmptyView()
}
}
var body: some View {
NavigationView {
ZStack {
navigationLink
List {
ForEach(resortStore.resorts, id: \.self.id) { resort in
Button(action: {
self.selectedResortId = resort.id
}) {
Text(resort.name)
}
.listRowBackground(self.selectedResortId == resort.id ? Color.gray : Color(UIColor.systemBackground))
}
}
}
.navigationBarTitle("Resorts")
.navigationBarItems(trailing: Button("Add Resort") {
self.addingNewResort = true
})
.sheet(isPresented: $addingNewResort) {
AddNewResort(selectedResortId: self.$selectedResortId)
.environmentObject(self.resortStore)
}
WelcomeView()
}
}
}
struct ResortView: View {
let resort: Resort
var body: some View {
Text("Resort View for resort name: \(resort.name).")
}
}
struct AddNewResort: View {
//bunch of properties
@Binding var selectedResortId: UUID?
@State var resortName = ""
@Environment(\.presentationMode) var presentationMode
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@EnvironmentObject var resortStore: ResortStore
var body: some View {
VStack {
Text("Add a Resort")
VStack {
TextField("Enter a name", text: $resortName)
//the rest of the fields
}
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(EdgeInsets(top: 20, leading: 30, bottom: 20, trailing: 30))
Button(action: {
let newResort = Resort(id: UUID(), name: self.resortName)
self.resortStore.resorts.append(newResort)
self.presentationMode.wrappedValue.dismiss()
if self.horizontalSizeClass == .regular {
self.selectedResortId = newResort.id
}
}) {
Text("Save Trip")
}
.padding(.trailing, 20)
}
}
}
struct WelcomeView: View {
var body: some View {
Text("Welcome View")
}
}
struct Resort {
var id: UUID
var name: String
}
Run Code Online (Sandbox Code Playgroud)
我开始撰写一系列有关 SwiftUI 列表视图中的导航的文章,在实现编程式导航时需要考虑很多要点。以下是我建议的描述此解决方案的内容:列表视图中的 SwiftUI 导航:编程导航。该解决方案目前适用于 iOS 13.4.1。SwiftUI 正在快速变化,因此我们必须不断检查。
这是我的上一篇文章,解释了为什么向每个列表行添加 NavigationLink 的更简单解决方案目前存在一些问题列表视图中的 SwiftUI 导航:探索可用选项
如果您有疑问,请告诉我,我很乐意尽我所能提供帮助。
| 归档时间: |
|
| 查看次数: |
3791 次 |
| 最近记录: |