SwiftUI Duplicate NavBars with Form Picker - swiftui

I am getting a second back button when I do a form picker.
First view comes from another view. (so that makes it the second view?)
After I choose the picker I get this.
There is nothing fancy in the code.
How can I avoid this?
NavigationView {
Form {
Text("text")
Picker(selection: .constant(1) , label: Text("Picker") ) {
Text("1").tag(1)
Text("2").tag(2)
}
Spacer()
}
}
.navigationBarTitle("Settings")
Thank you.

It looks like parent view already has NavigationView, so, by concept there should be only one navigation view in view hierarchy, you should just remove second one
// NavigationView { // << remove this one
Form {
Text("text")
Picker(selection: .constant(1) , label: Text("Picker") ) {
Text("1").tag(1)
Text("2").tag(2)
}
Spacer()
}
.navigationBarTitle("Settings") // << specify on Form !!

Related

Trouble With Constraints for a Navigation Link

Here is my code:
import SwiftUI
struct ContentView: View {
var link: some View {
NavigationLink(destination: OtherView()) {
Text("NLTitle")
}
.foregroundColor(.blue)
}
var body: some View {
NavigationView {
List {
ZStack {
HStack {
Text("1")
Spacer()
}.padding([.leading, .trailing], 20)
HStack {
Spacer()
Text("2")
.multilineTextAlignment(.center)
.frame(
alignment: .center
)
Spacer()
}
.padding([.leading, .trailing], 20)
HStack {
Spacer()
link
}.padding([.leading, .trailing], 20)
}
}
}
}
}
I have a NavigationLink (named 'link') in a list cell. I would like for the Text within 'link' to be to the rightmost side of the view. To try to accomplish this, I inserted 'link' in an HStack and put a Spacer() before it to try and push it to the rightmost part of the view. When I run the app though, the Text ends up in between Text("1") and Text("2") and I can't figure out why. I want Text("1") to be in the leftmost part of the view, Text("2") to be in the center of the view, and 'link' to be in the rightmost part of the view. I have provided visuals (the colors aren't important, I just wanted to make the different Texts clear):
Desired layout:
What I get instead:
I found that if I take everything out of the List view I get my desired layout. Also, if I keep everything in the List view and replace the NavigationLink with a Button I get my desired layout. The goal is to get the desired layout without having to change either of these aspects.
For the sake of clarity, I didn't include the code for OtherView() as I don't think it's necessary for this question.
The "quick" fix is to add fixedSize() to the NavigationLink
var link: some View {
NavigationLink(destination: Text("OtherView()")) {
Text("NLTitle")
}
.foregroundColor(.blue)
.fixedSize()
}
That will allow the link to shrink.

How to fix double back button in SwiftUI

I got 2 views. On the second view I have list of exercises and when I choose one of them and go inside I see double back. It's driving me crazy.
First one:
import SwiftUI
struct ProgrammView: View {
var body: some View {
NavigationView{
ScrollView(.vertical, showsIndicators: false) {
VStack {
Text("blabla")
.multilineTextAlignment(.center)
.font(.custom("AvenirNext-Bold", size: 30))
NavigationLink{
InsultHandProgram()
} label: {
Image("35")
.resizable()
.scaledToFit()
.padding(.horizontal)
.padding(.bottom, 7)
.shadow(radius: 5)
}
}
}
}
}
}
Second one:
import SwiftUI
struct InsultHandProgram: View {
let numbers = InsultProgram.getInsultProgram()
var body: some View {
NavigationStack {
List(numbers) { InsultProgram in
NavigationLink( InsultProgram.name, value: InsultProgram)
}
.navigationTitle("blabla")
.navigationDestination(for: InsultProgram.self) {
InsultProgram in InsultProgrammDetail(InsultProgram: InsultProgram)
}
}
}
I tried to change navigation stack. It's crushed.
If you use NavigationView, then it provides the navigation bars for all its child views. NavigationStack in your child view also wants to provide a navigation bar, and so you end up with two.
To remedy the situation you have some choices:
Remove the NavigationStack from your child view and let NavigationView manage everything.
Remove NavigationStack from you child view and replace NavigationView in your parent with a NavigationStack. This will work fine on iPhones, but doesn't adapt well to iPads.
Keep your navigation stack in the child view but replace NavigationView with NavigationSplitView. This came in with iOS16, as did NavigationStack. The two work well together so they don't step on each other's toes when it comes to setting up navigation bars.
Given you're already using other iOS 16 idioms such as navigationDestination I'd recommend approach 3.

SwiftUI: how to have image in list view not have same action as list item?

I have a list inside a view. Inside the list, items are iterated through to populate the list. When you click on each list item, I want to navigate to another view.
This is working as expected but I want to have a Button represented by a circle in each list item that can be clicked independently without navigating to the second view. Right now, clicking the circle just takes me to 2nd view. How can I accomplish this?
var body: some View {
NavigationView {
List {
ForEach(items) { item in
NavigationLink(
destination: OtherView(name: "test"),
label: {
Text("Navigate")
})
HStack {
Image("1")
.resizable()
.frame(width: 32.0, height: 32.0)
Button(action: addItem) {
Label("Add Item", systemImage: "circle")
}
}
}
}
}
}
You can not do this with List. You can use VStack or LazyVStack inside a ScrollView as an alternative solution

SwiftUI: Change navigation bar title in the more tab?

I am begining to get my haead around swiftUI. So I have a simple tabView inside a Navigation View as below.
import SwiftUI
struct BasicView: View {
var climbList: [ClimbDetail]
var body: some View {
NavigationView{
VStack{
Text("").navigationBarTitle("Climbers Log", displayMode:.inline)
TabView {
Text("Search").tabItem{
Image(systemName:"magnifyingglass")
Text("Search")
}
Text("Stats").tabItem{
Image(systemName:"list.dash")
Text("Stats")
}
ClimbList(climbs: climbList).tabItem{
Image(systemName: "square")
Text("Climbs")
}
Text("Log").tabItem{
Image(systemName:"square.and.pencil")
Text("Log")
}
Text("Profile").tabItem{
Image(systemName:"person.circle")
Text("Profile")
}
Text("Settings").tabItem{
Image(systemName:"gear")
Text("Settings")
}
Text("Add Climb").tabItem{
Image(systemName:"plus")
Text("Add Climb")
}
}
}
}
}
}
Genrally it works as expected, however as I have 7 tabs it defults to the 'More' tab for the 5th tab. This is fine and good for the user.
However my issue is when you click the 'More' tab you get the a title bar and edit button with 'More' as the title. Which appears below the title bar I have set above.
So my question is how can I hide my titleBar when the user is on the 'More' tab and only show it inside the other tabs?
First off all, thanks for the question. I didn't know Apple provides More page by default for too long TabBars. I always needed that.
Back to you question, you just need to rearrange things. First off all, make the TabBar top level. Then a NavigationView and here comes your content. Later on you might outsource every view, to an own file.
TabView {
NavigationView
{
VStack
{
Text("Search")
}
.navigationBarTitle("Climbers Log", displayMode:.inline)
}.tabItem {
Image(systemName:"magnifyingglass")
Text("Search")
}
Every view takes it own NavigationView.. and then it works.

SwiftUI Navigation Bar Title doesn't appear

I'm not sure if anything changed in Beta 3, however, when trying to add the NavigationBarTitle modifier to NavigationView, it does not show the text for the title? Any ideas?
NavigationView {
List(0 ..< 20) { item in
NavigationLink(destination: Text("1")) {
Text("Navigate 1")
}
}
}.navigationBarTitle(Text("Update")).navigationBarHidden(false)
}
The list shows but no title for the list in the NavigationView
You're setting .navigationBarTitle and .navigationBarHidden on NavigationView when they should be modifiers on List instead:
NavigationView {
List(0..<20) { item in
NavigationLink(destination: Text("1")) {
Text("Navigate 1")
}
}
.navigationBarTitle("Update")
.navigationBarHidden(false)
}
You can also just remove .navigationBarHidden(false) (unless you're setting it to true in a previous view or something).
Your code works fine and the navigationBarTitle is not outdated. It must be placed above (inside the Navigation View). Yes, it is sometimes confusing, it is necessary to remember this.
To the place where you currently have it .navigationBarTitle(Text ("Update")).navigationBarHidden(false) you need to set the modifier .navigationViewStyle(StackNavigationViewStyle ()), which means that you should always show the first screen regardless of the screen size.
var body: some View {
NavigationView {
List(0 ..< 20) { item in
NavigationLink(destination: Text("1")) {
Text("Navigate 1")
}
}
.navigationBarTitle(Text("Update"), displayMode: .automatic).navigationBarHidden(false)
}
// that means only show one view at a time no matter what device I'm working
.navigationViewStyle(StackNavigationViewStyle())
}