SwiftUI上的NavigationLink将视图两次推送

时间:2019-09-15 16:45:52

标签: ios swiftui

在SwiftUI中添加NavigationLink时,目的地会显示两次,例如:我点击NavigationLink并按下目的地,但是当我通过后退按钮或滑动手势关闭目的地时,它将再次按下目的地而无需点击链接。 这是我的代码中处理链接的部分:

var body: some View {
    HStack(spacing: 8.0) {
        ForEach(part.getReference()) { (imageRef: ReferenceImage) in
            ZStack(alignment: .topTrailing) {
                Image(uiImage: imageRef.getUIImage())
                .resizable()
                .frame(width: 90, height: 90)
                .cornerRadius(6)
                .onLongPressGesture {
                    print("looong")
                    self.managedObjectContext.delete(imageRef)
                    do {
                        try self.managedObjectContext.save()
                    } catch {
                        print("error deleting: \(error.localizedDescription)")
                    }
                }
                ZStack(alignment: .center) {
                    Circle()
                        .foregroundColor(Color.appColors.lightRose)
                        .opacity(0.7)
                        .frame(width: 35, height: 35)
                    Image(systemName: "arkit")
                        .imageScale(.large)
                }
                NavigationLink(destination:
                    ZStack {
                        Color.appColors.rose
                            .edgesIgnoringSafeArea(.top)
                        ReferenceARSwiftUIView(currentImage: imageRef.getUIImage())
                            .navigationBarTitle("AR Reference")
                    }

                ) {
                    EmptyView()
                    .frame(width: 90, height: 90)
                }

            }
        }.animation(.interpolatingSpring(stiffness: 0.5, damping: 0.5))

编辑01: 如建议的那样,我删除了代码中的一些噪音:

var part: Part
var body: some View {
    HStack(spacing: 8.0) {
        ForEach(part.getReference()) { (imageRef: ReferenceImage) in
            ZStack(alignment: .topTrailing) {
                Image(uiImage: imageRef.getUIImage())
                .resizable()
                .frame(width: 90, height: 90)
                .cornerRadius(6)
                NavigationLink(destination: ReferenceARSwiftUIView(currentImage: imageRef.getUIImage())) {
                    EmptyView()
                    .frame(width: 90, height: 90)
                }

            }
        }.animation(.interpolatingSpring(stiffness: 0.5, damping: 0.5))

编辑02: 我想我缩小了范围,基本上,如果我删除ForEach,则NavigationLink会正确推送到下一个视图。另外,根据我在ForEach阵列上拥有的itens数量,推送次数是相同的。

4 个答案:

答案 0 :(得分:4)

我通过将NavigationLink的标签设置为模型项的唯一ID来解决此问题。

假设您有一个imageRef的ID,即ReferenceImage类。

var part: Part
var body: some View {
    HStack(spacing: 8.0) {
        ForEach(part.getReference()) { (imageRef: ReferenceImage) in
            ZStack(alignment: .topTrailing) {
                Image(uiImage: imageRef.getUIImage())
                .resizable()
                .frame(width: 90, height: 90)
                .cornerRadius(6)
                NavigationLink(destination: ReferenceARSwiftUIView(currentImage: imageRef.getUIImage()), tag: imageRef.id) {
                    EmptyView()
                    .frame(width: 90, height: 90)
                }

            }
        }.animation(.interpolatingSpring(stiffness: 0.5, damping: 0.5))
NavigationLink(destination: ReferenceARSwiftUIView(currentImage: imageRef.getUIImage()), tag: imageRef.id)

答案 1 :(得分:1)

是的,将List更改为ScrollView可以帮助我解决类似的情况。


                    ScrollView {
                        if !usersViewModel.isLoading {
                            ForEach(self.usersViewModel.users, id: \.id) { user in
                                NavigationLink(destination: UserDashboardView(showDashboardDetail: $showDashboardDetail, user: user)) {
                                    VStack(alignment: .leading) {
                                        NetworkCardView(user: user)
                                    }
                                    .frame(width: screen.size.width - 60, height: 250)
                                    .padding(.top)
                                }
                            }
                            .listRowBackground(AppColor())
                        }
                    }

答案 2 :(得分:0)

我无法重现您的问题,因为即使精简版也包含您声明的类型,但未包含在问题中。

几件事:

如果要使用NavigationLink,则需要将视图嵌入NavigationView中。

如果您在ForEach中使用HStack,则有可能会耗尽空间来显示所有元素,因此将其包装在{ {1}}。

最后但并非最不重要的一点:在ScrollView内,您必须将ForEach设为顶层视图,并对其内容进行其他任何查看:

NavigationLink

答案 3 :(得分:0)

我确定Part符合Identifiable协议并具有id属性。

NavigationLink的目的地被多次显示,因为您在Part循环中有多个id实例,它们具有完全相同的身份forEach

只需确保Part的每个实例都有一个唯一的id,一切都会按预期进行。