SwiftUI:在带有 SidebarListStyle 的 NavigationView/List 中选择 NavigationLink

标签 swiftui navigationview navigationlink sidebarliststyle

我想以编程方式在 NavigationLink/NavigationView 中选择特定的 List
以下代码在 iPhone 上的纵向或横向模式下都可以正常工作 == 在列表除了其目标 View 之外不是永久可见的情况下。
enter image description here
代码:

struct ContentView: View {

private let listItems = [ListItem(), ListItem(), ListItem()]
@State var selection: Int? = 0

var body: some View {
    NavigationView {
        
        List(listItems.indices) {
            index in
            
            let item = listItems[index]
            let isSelected = (selection ?? -1) == index
            
            NavigationLink(destination: Text("Destination \(index)"),
                           tag: index,
                           selection: $selection) {
                
                Text("\(item.name) \(index) \(isSelected ? "selected" : "")")
                
            }
            
        }
    
    }
    .listStyle(SidebarListStyle())
    .onAppear(perform: {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
            selection = 2
        })
    })
    }

}


struct ListItem: Identifiable {
    var id = UUID()
    var name: String = "Some Item"
}
但它在横向模式下的 iPad 上失败:虽然导航本身有效(目的地显示正确),但 NavigationLink 保持未选中状态。
→ 如何以在 iPad 上显示的方式选择 NavigationLink?

最佳答案

这是可能的方法。这个想法是通过 View 模型以编程方式激活导航链接,但将模型级选择和呈现(由链接拥有)选择分开。
使用 Xcode 12b3/iOS+iPadOS 14 测试。

class SelectionViewModel: ObservableObject {
    var currentRow: Int = -1 {
        didSet {
            self.selection = currentRow
        }
    }

    @Published var selection: Int? = nil
}

struct SidebarContentView: View {
@StateObject var vm = SelectionViewModel()
private let listItems = [ListItem(), ListItem(), ListItem()]

var body: some View {
    NavigationView {

        List(listItems.indices) {
            index in

            let item = listItems[index]
            let isSelected = vm.currentRow == index

            Button("\(item.name) \(index) \(isSelected ? "selected" : "")") { vm.currentRow = index }
            .background (
                NavigationLink(destination: Text("Destination \(index) selected: \(vm.currentRow)"),
                               tag: index,
                               selection: $vm.selection) {
                    EmptyView()
                }.hidden()
            )
        }

    }
    .listStyle(SidebarListStyle())
    .onAppear(perform: {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
            vm.currentRow = 2
        })
    })
    }
}

关于SwiftUI:在带有 SidebarListStyle 的 NavigationView/List 中选择 NavigationLink,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63229033/

相关文章:

ios - SwiftUI:如何关闭模式表,然后一起执行导航链接

swift - 多个 ui 元素破坏 WidgetExtension

ios - 如何迭代数组来初始化按钮?

java - 如何更改导航 View 菜单项和文本的大小??如何更改菜单之间的空间?

java - 通过按导航 View 中的 id 重新加载导航 View 内容

listview - SwiftUI - 列表导航不适用于 iPhone

ios - 使用 URL 在 Swift 中显示电话号码的所有系统选项

ios - SwiftUI Firestore 查询游标分页不起作用

android - 如何显示带有抽屉导航菜单项的指示器

ios - 我正在使用 NavigationLink 在 View 之间导航,但它在 SwiftUI 中的单个 View 中不起作用