【问题标题】:SwiftUI: Selecting inner NavigationList item from ToolbarSwiftUI:从工具栏中选择内部 NavigationList 项
【发布时间】:2021-01-17 21:17:43
【问题描述】:

我正在尝试从工具栏按钮突出显示内部列表项。这实际上是为了在点击新建按钮后突出显示一个新条目。

import SwiftUI

var listItems = ["Item 1", "Item 2", "Item 3"]
var secondItems = ["Second 1", "Second 2", "Second 3"]

struct ContentView: View
{
    @State var select: String? = "Item 1"
    @State var second: String? = "Second 1"

    var body: some View
    {
        NavigationView
        {
            List
            {
                ForEach((0..<listItems.count), id: \.self)
                {index in
                    NavigationLink(destination: ListView(secondSelection: self.second), tag: listItems[index], selection: $select)
                    {
                        Text(listItems[index])
                    }
                }
            }
        }
        .toolbar
        {
            Button(action: {addNewItem()})
            {
                Label("Select", systemImage: "square.and.pencil")
            }
            Button(action: {selectItem(index: 1)})
            {
                Label("Select", systemImage: "1.circle")
            }
            Button(action: {selectItem(index: 2)})
            {
                Label("Select", systemImage: "2.circle")
            }
            Button(action: {selectItem(index: 3)})
            {
                Label("Select", systemImage: "3.circle")
            }
        }
    }
    
    func addNewItem()
    {
        let c = secondItems.count + 1
        secondItems.append("Second \(c)")
    }
    
    func selectItem(index: Int)
    {
        print ("\(index) selected")
        self.second = "Second \(index)"
    }
}

struct ListView: View {
    
    @State var secondSelection: String? = "Item 1"
    @State var select: String? = nil

    init(secondSelection: String?)
    {
        self.secondSelection = secondSelection
    }
    
    var body: some View
    {
        NavigationView
        {
            List()
            {
                ForEach(secondItems, id: \.self)
                {item in
                    NavigationLink(destination: DetailView(item: item), tag: item, selection: $select)
                    {
                        Text("\(item)")
                    }
                 }
            }
        }
     }
}

struct DetailView: View
{
    @State var item: String

    var body: some View
    {
        Text(item)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

单击工具栏中的“1”、“2”和“3”按钮应突出显示“Second 1”、“Second 2”和“Second 3”项。我可以突出显示外部列表,但不能突出显示内部列表。目前它什么也没做。

我最终要做的是单击 addNewItem 并看到新项目出现在第二个列表中,突出显示并准备就绪。

更新

我在这方面取得了一些进展。

import SwiftUI

class SelectedItem: ObservableObject
{
    static let shared = SelectedItem() //singleton
    
    @Published var item: String? = "Item 1"
    @Published var second: String? = "Second 2"
}

var listItems = ["Item 1", "Item 2", "Item 3"]
var secondItems = ["Second 1", "Second 2", "Second 3"]

struct ContentView: View
{
    @ObservedObject var selectedItem = SelectedItem.shared

    var body: some View
    {
        NavigationView
        {
            List
            {
                ForEach((0..<listItems.count), id: \.self)
                {index in
                    NavigationLink(destination: ListView(), tag: listItems[index], selection: $selectedItem.item)
                    {
                        Text(listItems[index])
                    }
                }
            }
        }
        .toolbar
        {
            Button(action: {addNewItem()})
            {
                Label("Select", systemImage: "square.and.pencil")
            }
            Button(action: {selectItem(index: 1)})
            {
                Label("Select", systemImage: "1.circle")
            }
            Button(action: {selectItem(index: 2)})
            {
                Label("Select", systemImage: "2.circle")
            }
            Button(action: {selectItem(index: 3)})
            {
                Label("Select", systemImage: "3.circle")
            }
        }
    }
    
    func addNewItem()
    {
        let index = secondItems.count + 1
        secondItems.append("Second \(index)")
        selectItem(index: index)
        
    }
    
    func selectItem(index: Int)
    {
        print ("\(index) selected")
        let second = "Second \(index)"
        selectedItem.second = second
    }
}

struct ListView: View
{
    @ObservedObject var selectedItem = SelectedItem.shared

    var body: some View
    {
        NavigationView
        {
            List()
            {
                ForEach(secondItems, id: \.self)
                {item in
                    NavigationLink(destination: DetailView(item: item), tag: item, selection: $selectedItem.second)
                    {
                        Text("\(item)")
                    }
                }
            }
        }
    }
}

struct DetailView: View
{
    @State var item: String

    var body: some View
    {
        Text(item)
    }
}

现在,当我单击其中一个数字按钮时,它会突出显示内部文本。烦人的是,如果我刚刚将一个新项目附加到列表中,它不会选择内部项目。

实际上,这在某些时候确实有效。似乎如果您反复单击它,它每隔一次就会起作用,直到它离开屏幕,它每次都会开始工作。我怀疑这是一个时间问题。

【问题讨论】:

    标签: swiftui toolbar swiftui-navigationlink


    【解决方案1】:

    您需要将绑定传递给内部列表而不是值,例如

    NavigationLink(destination: ListView(secondSelection: $second),    // << here !!
       tag: listItems[index], selection: $select)
    

    并将其用作选择

    struct ListView: View {
        
        @Binding var secondSelection: String?   // << here !!
        @State var select: String? = nil
    
        var body: some View
        {
            NavigationView
            {
                List(selection: $secondSelection)     // << and here !!
                {
                    ForEach(secondItems, id: \.self)
                    {item in
                        NavigationLink(destination: DetailView(item: item), tag: item, selection: $select)
                        {
                            Text("\(item)")
                        }
                     }
                }
            }
         }
    }
    

    注意: 众所周知,不同视图层次结构之间的绑定不可靠,因此我建议将此选择重构为基于 ObservableObject 的视图模型,该模型可以在任何地方通过引用传递。

    【讨论】:

    • 感谢您的回答,但这并没有改变任何事情。单击 1、2 和 3 按钮时,不会突出显示任何内容。
    猜你喜欢
    • 2022-11-10
    • 2011-07-10
    • 2021-09-13
    • 1970-01-01
    • 2015-08-14
    • 2021-05-10
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    相关资源
    最近更新 更多