没有公开指示器的SwiftUI NavigationButton?

时间:2019-06-09 16:24:28

标签: swiftui

在创建带有行的列表以推送到新视图时,SwiftUI是否会自动添加显示指示器“>”?如果不希望如何删除它?

    NavigationView {
        List {
            NavigationButton(destination: DetailView()) {
                ListItem()
            }
        }
        .navigationBarTitle(Text("Some title"))
    }

在UITableViewCell上,您将“附件”设置为“无”,但是如何在SwiftUI中做到这一点?

18 个答案:

答案 0 :(得分:8)

Swift 5,Xcode11。ZStack完美运行。

var body: some View {
    NavigationView {
        List {
            ForEach(viewModel.currenciesViewModel) { cellViewModel in
                ZStack {
                    cellViewModel.makeView()
                    NavigationLink(destination: ChooseCurrencyListView()) {
                        EmptyView()
                    }
                    .buttonStyle(PlainButtonStyle())
                }
            }
        }
        .navigationBarHidden(true)
        .navigationBarTitle("", displayMode: .inline)
    }
}

答案 1 :(得分:8)

最简单的一种。列表中每个项目的内容。

ZStack {
   NavigationLink(destination: DetailView()) {
       EmptyView()
   }.hidden()
   RowView()
}

答案 2 :(得分:7)

从beta 6开始,它运行良好:

struct SwiftUIView: View {   
    var body: some View {

        NavigationView {
            List {
                HStack {
                    Text("My Cell Content")
                    NavigationLink(destination: Text("destination"), label: {
                        EmptyView()
                    })
                }
            }
        }
    }
}

答案 3 :(得分:5)

设置NavigationLink宽度并将其隐藏对我来说是成功的秘诀

List {
  ForEach(pages) { page in
    HStack {
      Text("Something")

      NavigationLink(destination: Text("Somewhere")) {
        EmptyView()
      }
      .frame(width: 0)
      .opacity(0)
    }
  }
}

答案 4 :(得分:5)

如果使用列表,您可以做的是将导航链接设置为隐藏,并将其框架宽度设置为零。

    HStack{
            Button(action: {self.statusShow = 1}, label: {
                Image(systemName: "info.circle")
            })
            NavigationLink(destination: StimulatorSettingView(),
                           tag: 1,
                           selection: self.$statusShow){
                            EmptyView()

            }.hidden().frame(width: 0)
        }

这对我有用。

答案 5 :(得分:4)

您不必使用NavigationLink来直接包装Label。只要链接在视图层次结构中的任何位置,它都将起作用。

在这里,我将其包装在一个按钮中,该按钮使您可以在推动视图之前触发操作。由于NavigationLink的标签具有EmptyView,因此公开指示符不可见。您也可以使用ButtonStyle设置样式。

struct NavigationButton<Destination: View, Label: View>: View {
    var action: () -> Void = { }
    var destination: () -> Destination
    var label: () -> Label

    @State private var isActive: Bool = false

    var body: some View {
        Button(action: {
            self.action()
            self.isActive.toggle()
        }) {
            self.label()
              .background(NavigationLink(destination: self.destination(), isActive: self.$isActive) {
                  EmptyView() 
               })
        }
    }
}

并使用它:

NavigationButton(
    action: { print("tapped!") },
    destination: { Text("Pushed View") },
    label: { Text("Tap me") }
  )

答案 6 :(得分:4)

对我来说很好!

import SwiftUI

struct LandmarkList: View {
    var body: some View {
        NavigationView {
            List(landmarkData) { landmark in
                LandmarkRow(landmark: landmark)
                NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
                    EmptyView()
                }
            }
            .navigationBarTitle(Text("Landmarks"))
        }
    }
}

struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(["iPhone SE", "iPhone 11 Pro Max"], id: \.self) { deviceName in
            LandmarkList()
                .previewDevice(PreviewDevice(rawValue: deviceName))
                .previewDisplayName(deviceName)
        }
    }
}

enter image description here

答案 7 :(得分:2)

作为解决方法,我建议添加如下的.padding修饰符:

NavigationView {
        List {
            NavigationButton(destination: DetailView()) {
                ListItem()
            }
        }
        .navigationBarTitle(Text("Some title"))
    }
    .padding(.trailing, -32.0)

因此您将获得不可见显示的行:

Result

答案 8 :(得分:2)

NavigationLink是我们应该在NavigationView内的范围内定义的内容。 但是,当我们使用NavigationLink并将其附加到封闭视图时,为了将同一NavigationLink与其他视图重用,我们使用tag来区分不同的目的地

struct SwiftUIView: View {
@State private var viewState: Int? = 0

var body: some View {

    NavigationView {
                VStack {
                    NavigationLink(destination: Text("View 1"), tag: 1, selection: $viewState) {
                        EmptyView()
                    }

                    NavigationLink(destination: Text("View 2"), tag: 2, selection: $viewState) {
                        EmptyView()
                    }

                    Text("First View")
                        .onTapGesture {
                            self.viewState = 1
                        }

                    Text("Second View")
                        .onTapGesture {
                            self.viewState = 2
                        }
                    }
            }
    }
} 

在这里,我们将Hashable属性与NavigationLinks中存在的所有VStack绑定在一起,以便在点击某个特定视图时,我们可以通知应该目的地通过设置Bindable属性的值来打开。 如果我们没有通过设置tag的值来通知正确的目的地,则始终可以单击NavigationLink闭包内定义的视图,而没有其他选择。

使用这种方法,您不需要将所有可点击的视图都包装在NavigationView内,对任何视图的任何操作都可以通过设置NavigationLink来使用任何tag

谢谢,希望能对您有所帮助。

答案 9 :(得分:1)

尚无文档,因此您可以暂时使用 ScrollView

  NavigationView {
        ScrollView {
            ForEach(0...100){ x in
                NavigationButton(destination: Text("ss")) {
                    HStack {
                          Text(String(x))
                          Spacer()
                        }
                        .padding()
                        .background(Color.white)
                        .shadow(radius:1,y:1)
                }
             }
             .frame(width: UIScreen.main.bounds.width - 32)
             .padding()
        }
    }

enter image description here

答案 10 :(得分:1)

使用.frame(width: 0).opacity(0.0)

NavigationView {
  List {
    ForEach(options) {
      option in
        ZStack {
          YourView(option: option)
          NavigationLink(destination: ProductListView(),
            label: {
              EmptyView()
            }).frame(width: 0).opacity(0.0)
        }.listRowInsets(EdgeInsets())
    }
  }.navigationBarHidden(true)
}

答案 11 :(得分:0)

如果你需要 List 和 NavigationLink 的儿童行为,同时没有额外的披露者,我想推广这个棘手的解决方案,要点在 HStack

var body: some View {
    NavigationView {
        List(items, children: \.items) { item in
            ZStack {
               NavigationLink(destination: DetailsView()) {
                   EmptyView()
               }.hidden()
                HStack {
                    RowView(item: item)
                    Spacer()
                }
            }
        }
    }
}

答案 12 :(得分:0)

您也可以将其放在.background修饰符中:

List {
    Text("Go to...")
        .background(NavigationLink("", destination: Text("Detail View")))
}

如果文本上已经具有background修饰符,则可以将文本包装在HStack中并将background应用于HStack。

答案 13 :(得分:0)

使用List()时,如果没有解决方法,则无法删除公开指示器。 但是,如果没有List(),还有另一种简单的方法可以做到。 代替List(),您可以使用其中具有ForEach()的ScrollView()

既不费力也不费时间,但是它使NavigationLink的显示指示器消失,没有任何技巧或变通办法,无需任何额外费用!让您可以通过一个不错的普通按钮轻松导航到另一个视图。

答案 14 :(得分:0)

只是来这里寻找问题的答案,但是没有一个建议的解决方案对我有用(不能有一个空洞的视图,因为我想在列表行中放一些东西;我已经在弄乱填充(以及增加尾随填充似乎没有用)...我要放弃了,然后我发生了什么:如果您提高列表行本身的Z索引怎么办?似乎不太可能,但是我尝试了一下,我该死的,它成功了!我感到非常惊喜,我想分享...

例如:

// in body of your list row view
HStack(alignment: .top, spacing: 0.0) {
    // stuff ...
}
.zIndex(9999999999)

答案 15 :(得分:0)

这有助于将模型推入并传递到下一个导航视图控制器。

struct ContentView : View {
    @State var model = PostListViewModel()

    var body: some View {
        NavigationView {
            List(model.post) { post in
                ListCell(listData: post)
                }.navigationBarTitle(Text("My Post"))
        }
    }

}

struct ListCell: View {
    var listData: Post
    var body: some View {
        return NavigationButton(destination: DetailContentView(post: listData)) {
            HStack {
                ImageRow(model: listData) // Get image
                VStack(alignment: .leading) {
                    Text(listData.login).font(.headline).lineLimit(nil)
                    Text(listData.url).font(.subheadline).lineLimit(nil)
                    }.padding(.leading, 10)
                }.padding(.init(top: 5, leading: 0, bottom: 5, trailing: 0))
        }
    }
}

答案 16 :(得分:-1)

将按钮放入滚动视图后,公开按钮将被隐藏。只要确保禁用滚动指示器即可。

答案 17 :(得分:-2)

删除List并仅使用ForEach可以很好地与导航链接一起使用。您只需要创建自己的列表行。这对我有用

NavigationView {
   ForEach(pages) {
    page in
      NavigationLink(destination: DetailView()) {
         ListItem()
     }
   }
}