This question already has an answer here:
SwiftUI iOS14 - NavigationView + List - Won't fill space
(1 answer)
Closed 2 years ago.
If I wrap a VStack with a List inside a NavigationView, the resulting list is indented, see image. This is not the expected formatting because I'd want the list to cover the whole screen width.
How can I fix this and why does this happen?
Note: This indentation behavior would go away if I remove the VStack, but here I do want to include the Text box ("Something...") inside the NavigationView, because I want it to go away once a user clicks on an item.
Full code below, Xcode 12.3:
import SwiftUI
struct ListView: View {
var items: [String]
var body :some View {
List {
ForEach(items, id: \.self) { item in
NavigationLink(destination: Text(item)){
Text(item)
}
}
}
}
}
struct ContentView: View {
var body: some View {
NavigationView{
VStack{
Text("Something that should disappear when I click on the item")
ListView(items: ["a", "b"])
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Hey all you need to do is add the modifier for a .liststyle
.listStyle(InsetListStyle())
Also you should be aware that there is no way to remove the chevron symbol on lists
import SwiftUI
struct ListView: View {
var items: [String]
var body :some View {
List {
ForEach(items, id: \.self) { item in
NavigationLink(destination: Text(item)){
Text(item)
}
}
}.listStyle(InsetListStyle())
}
}
struct ContentView: View {
var body: some View {
NavigationView{
VStack{
Text("Something that should disappear when I click on the item")
ListView(items: ["a", "b"])
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Related
NavigationView nests TabView, I have a List, and push to the next page
When the application returns to the background and returns to the active state, the push page automatically pops up.
If TabView nests NavigationView, there will be no problem, but I want NavigationView to nest TabView, is there any way to solve it
struct ContentView: View {
var body: some View {
NavigationView {
TabView {
List {
ForEach(0..<30) { index in
RowView(index: index)
}
}
}
}
}
}
struct RowView: View {
var index: Int
#State var userViewActive: Int?
var body: some View {
NavigationLink {
Text("Hello, world!")
} label: {
Text("Hello, world!")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
In a tabview each tab should manage its own view state. Aka
Every tab should have it's own navigation view. If you add this, you will see that your problem is solved.
I have discovered a regression in watchOS 8.1RC with NavigationLink triggered from a TabView.
It's immediately dismissed.
It was working in watchOS 8.0 or in Simulator (watchOS 8.0).
Do you know a workaround ?
Thanks
Sample code:
import SwiftUI
#main
struct TestNavigationApp: App {
var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
}
}
}
}
struct ContentView: View {
var body: some View {
List {
NavigationLink(destination: ContentView1()) {
Text("To TabView")
}
}
}
}
struct ContentView1: View {
var body: some View {
TabView {
NavigationView {
NavigationLink(destination: ContentView2()) {
Text("To ContentView2")
}
}
VStack {
Text("Screen2")
}
}
}
}
struct ContentView2: View {
var body: some View {
Text("ContentView2")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I'm experiencing the same issue with watchOS 8.1 (and 8.3 beta) while it was working with previous watchOS versions.
We were able to get it working again by moving the NavigationView inside the TabView. This workaround isn't ideal at all but it does seem to work.
#State private var tabSelection = 1
var body: some Scene {
WindowGroup {
TabView(selection: $tabSelection) {
NavigationView {
// List goes here
}
.tag(1)
VStack(alignment: .center, spacing: 12, content: {
// content 2nd tab: we didn't have a list in the 2nd tab
})
.tag(2)
}
}
}
However, there are 2 things impacted with this fix:
I didn't get the navigationBarTitle working, so there won't be a title on top of the screen.
If you click on an item in the list, it will navigate to your page (as expected) but the TabView dots at the bottom of the screen will remain.
I am trying to add a Navigation view that goes from my ContentView to my list items inside of my SectionView and then goes to my DetailView...i'm getting an error and i'm not sure why? im trying to nav link SelectionView( codeName: "Y")
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
List {
NavigationLink("Y", destination:codeName.
(model: .codeName))
List (models) { model in
SelectionView(codeName: model.codeName)
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewLayout(.device)
.preferredColorScheme(.dark)
.previewDevice("iPhone 13 Pro Max")
}
}
#endif
}
}
The destination also should be a view.
struct ContentView: View {
var body: some View {
NavigationView {
List {
ForEach(0 ..< 5) { item in
NavigationLink(
destination: Text("Destination \(item)"),
label: {
Text("Hello, world! \(item)")
.padding()
})
}
}
}
}
}
When I embed a List grouped into Sections into a NavigationView the section headers become collapsible. I'd like to keep them non-collapsible, just like when the List is not embedded into the NavigationView.
My current code (with the NavigationView):
import SwiftUI
struct MyGroup {
var name:String, items:[String]
}
struct ContentView: View {
var groups : [MyGroup] = [
.init(name: "Animals", items: ["🐕","🐩","🐂","🐄","🐈","🦩","🐿","🐇"]),
.init(name: "Vehicles", items: ["🚕","🚗","🚃","🚂","🚟","🚤","🛥","⛵️"])]
var body: some View {
NavigationView {
VStack {
List {
ForEach(groups, id: \.self.name) { group in
Section(header: Text(group.name)) {
ForEach(group.items, id:\.self) { item in
Text(item)
}
}
}
}
}.navigationTitle("collections")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
It is default style applied, you can make it explicitly set for List like below (tested with Xcode 12 / iOS 14)
List {
ForEach(groups, id: \.self.name) { group in
Section(header: Text(group.name)) {
ForEach(group.items, id:\.self) { item in
Text(item)
}
}
}
}.listStyle(InsetGroupedListStyle()) // or GroupedListStyle
Just using the SidebarListStyle in listStyle modifier
.listStyle(SidebarListStyle())
In case you're stumbling on this... The issue doesn't have anything to do with being embedded in a NavigationView as the OP and #Danial mentioned. It's because it's embedded in the the VStack at the first level of the NavigationView in the example code. Seems like a SwiftUI bug to me.
I have some master detail in Swift UI. Here it is:
import SwiftUI
struct MenuItemView: View {
var title: String
#Environment(\.presentationMode) var presentationMode
private var btnBack : some View { Button(action: {
//if landscape just show list on the left
//same if swipe from left
//how to do that???
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Menu")
}
}
var body: some View {
Text(title)
.navigationBarTitle(Text(title), displayMode: .inline)
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: btnBack)
}
}
struct ContentView: View {
#State private var items: [String] = ["Home", "Events", "Topics", "Latest"]
var body: some View {
NavigationView {
List {
ForEach(self.items, id: \.self) { item in
NavigationLink(destination: MenuItemView(title: item)) {
Text(item)
}
}
}
.listStyle(GroupedListStyle())
.navigationBarTitle(Text("TimelessToday"), displayMode: .inline)
Text("Initial")
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
This is working exactly as I plan in portrait mode for any IPhone. But in landscape for IPhone 11 or for IPad in portrait I want "Menu" button when pressed to show left menu with list of items. Same like when doing swipe from left side to show it.
Can't understand how to do this.