【问题标题】:SwiftUI NavigationLink in the TitleBar pushes the view twice, a Button doing the same thing is notTitleBar 中的 SwiftUI NavigationLink 两次推送视图,一个 Button 做同样的事情不是
【发布时间】:2021-05-22 00:13:04
【问题描述】:

这很烦人。 NavigationBar 中的 Edit 按钮推动 View 两次。我做了一个测试按钮,它的行为正确地做同样的事情:

import SwiftUI

struct DetailListPage: View {
@Environment(\.presentationMode) var presentationMode

var listName: ListNames

//    @State private var isEditDetailListPageShowing = false
@State private var selection: String? = nil

var body: some View {
    Form {
        Section(header: Text(listName.title ?? "")
                    .font(.title)
                    .padding()) {

            Text(listName.listDetail ?? "Nothing is set yet!")
                .multilineTextAlignment(.leading)
                .padding()
                .cornerRadius(12)
        }
        NavigationLink(destination: EditDetailListPage(listName: listName)) {
            Button {
                
            } label: {
                Text("Edit Page")
            }
        }
    }
    .navigationBarBackButtonHidden(true)
    
    .toolbar {
        ToolbarItem(placement: .navigationBarTrailing) {
            Button {
                self.presentationMode.wrappedValue.dismiss()
            } label: {
                Text("Cancel")
            } .padding()
            //Edit List Detail
        }
        ToolbarItem(placement: .navigationBarTrailing) {
            NavigationLink(
                destination: EditDetailListPage(listName: listName)) {
                Text("Edit")
            }

    }
    
}
}

上面的 Text("Edit") 将视图推送两次。 它上面的 Button 动作正确。想使用导航条而不是按钮。

【问题讨论】:

    标签: swiftui swiftui-navigationlink


    【解决方案1】:

    适用于我,在 macos 11.4、xcode 12.5、目标 ios 14.5 和 macCatalyst 11.3 上。 可能是导致问题的其他代码(或设置/系统)。 你用的是什么系统?向我们展示缺少的代码以及如何调用视图。如果下面的测试代码不适合您,请告诉我们。

    这是我使用的测试代码:

    @main
    struct TestErrorApp: App {
        var body: some Scene {
            WindowGroup {
                ContentView()
            }
        }
    }
    struct EditDetailListPage: View {
        var listName: [String]
        var body: some View {
            Text("EditDetailListPage")
        }
    }
    
    struct ContentView: View {
        var body: some View {
            NavigationView {
                DetailListPage(listName: ["test var"])
            }.navigationViewStyle(StackNavigationViewStyle())
        }
    }
    
    struct DetailListPage: View {
        @Environment(\.presentationMode) var presentationMode
        var listName: [String]
        //  @State private var isEditDetailListPageShowing = false
        @State private var selection: String? = nil
        
        var body: some View {
            Form {
                Section(header: Text("header string")
                            .font(.title)
                            .padding()) {
                    Text("Nothing is set yet!")
                        .multilineTextAlignment(.leading)
                        .padding()
                        .cornerRadius(12)
                }
                NavigationLink(destination: EditDetailListPage(listName: listName)) {
                    Button {
                    } label: {
                        Text("Edit Page")
                    }
                }
            }
            .navigationBarBackButtonHidden(true)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button {
                        self.presentationMode.wrappedValue.dismiss()
                    } label: {
                        Text("Cancel")
                    } .padding()
                    //Edit List Detail
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    NavigationLink(
                        destination: EditDetailListPage(listName: listName)) {
                        Text("Edit")
                    }
                }
            }
        }
    }
    
    struct ListFrontPage: View {
        
        @Environment(\.presentationMode) var presentationMode
        @Environment(\.managedObjectContext) var managedObjectContext
        
        @State private var isAddNewListShowing = false
        
        var listNames: FetchRequest<ListNames>
    
        init() {
            listNames = FetchRequest<ListNames>(entity: ListNames.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \ListNames.sort, ascending: true)], animation: .default)
        }
        
        var body: some View {
            VStack {
                List() {
                    Text("Accounts")
                        .frame(maxWidth: .infinity)
                        .font(.system(size: 30, weight: .heavy, design: .default))
                    ForEach (listNames.wrappedValue) { listName in
                        NavigationLink(destination: DetailListPage(listName: listName)) {
                            Text("\(listName.title ?? "")")
                        }
                    }
                    .onDelete(perform: deleteItems)
                    .onMove(perform: moveItem)
                }
                Spacer()
                ZStack {
                    NavigationLink(destination: AddNewList()) {
                        Image(systemName: "plus.circle.fill").font(.system(size: 64))
                    }
                }
            }
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(leading: Button {
                self.presentationMode.wrappedValue.dismiss()
            } label: {
                Image(systemName: "chevron.backward")
                Label("Back", image: "")
            }, trailing: EditButton())
            .navigationBarTitle(Text("Account Management"))
        }
        
        private func deleteItems(offsets: IndexSet) {
            withAnimation {
                offsets.map { listNames.wrappedValue[$0] }.forEach(CoreDataHelper.sharedManager.deleteItems)
                
            }
        }
        
        private func moveItem(from offsets: IndexSet, to destination: Int)
        {
            print("From: \(String(describing: offsets)) To: \(destination)")
            // Make an array of items from fetched results
            var revisedItems: [ ListNames ] = listNames.wrappedValue.map{ $0 }
            
            // change the order of the items in the array
            revisedItems.move(fromOffsets: offsets, toOffset: destination )
                    
            // update the userOrder attribute in revisedItems to
            // persist the new order. This is done in reverse order
            // to minimize changes to the indices.
            for reverseIndex in stride( from: revisedItems.count - 1,
                                        through: 0,
                                        by: -1 )
            {
                revisedItems[ reverseIndex ].sort =
                    Int16( reverseIndex )
            }
        }
    }
    

    【讨论】:

    • 这是一项不错的工作。感谢您的测试。这在我的 11.3 xcode 12.5 上也可以正常工作。难以复制。这是一个核心数据项目。有几个视图b4 可以到达DetailPage。我要编辑我的帖子并显示即时视图,调用视图。再次感谢您的尝试。至少我知道它应该可以工作。
    • @JamesBond 编辑了错误的帖子(编辑你的question,而不是别人的答案)
    猜你喜欢
    • 2020-01-16
    • 1970-01-01
    • 2022-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    相关资源
    最近更新 更多