SwiftUI Picker options add padding tvOS - swiftui

It seems like there's no way to modify the Picker options view's paddings. I tried different solutions from adding the padding to the enclosing NavigationView to the TextView inside the ForEach of the Picker view itself. Any clue?
Here's the view hierarchy:
NavigationView {
VStack {
Text("Debug settings")
.font(.sans(.title2))
Spacer()
.frame(height: 56)
List {
Section(header: Text("Environments").font(.sans(.body))) {
Picker("Environment", selection: $selectedEnvironment) {
ForEach(Constants.Environment.allCases) { environment in
Text(environment.rawValue.capitalized).tag(Optional<String>(environment.host))

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.

LazyVGrid onTapGesture navigate to next screen swiftUI

I am quite new to swiftUI. I have created a grid view on tapping on which I want to go to next screen. But somehow I am not able to manage to push to next screen. I am doing like this:
var body: some View {
NavigationView {
ScrollView {
LazyVGrid(columns: gridItems, spacing: 16) {
ForEach(viewModel.pokemon) { pokemon in
PokemonCell(pokemon: pokemon, viewModel: viewModel)
.onTapGesture {
NavigationLink(destination: PokemonDetailView(pokemon: pokemon)) {
Text(pokemon.name)
}
}
}
}
}
.navigationTitle("Pokedex")
}
}
Upon doing like this, I am getting a warning stating
Result of 'NavigationLink<Label, Destination>' initializer is unused
Can someone please guide me, how to do this?
.onTapGesture adds an action to perform when the view recognizes a tap gesture. In your case you don't need to use .onTapGesture. If you want to go to another view when cell is tapped you need to write NavigationLink as below.
NavigationLink(destination: PokemonDetailView(pokemon: pokemon)) {
PokemonCell(pokemon: pokemon, viewModel: viewModel)
}
If you want to use .onTapGesture, another approach is creating #State for your tapped cell's pokemon and using NavigationLink's isActive binding. So when user tap the cell it will change the #State and toggle the isActive in .onTapGesture. You may need to add another Stack (ZStack etc.) for this.
NavigationView {
ZStack {
NavigationLink("", destination: PokemonDetailView(pokemon: pokemon), isActive: $isNavigationActive).hidden()
ScrollView {
// ...

SwiftUI: List rows get highlighted when interacting with other views if inside a TabView

If a List is placed along with other views within a VStack which defines one page within a TabView with PageTabViewStyle, interacting (tap, long pressing) with the other views causes all (visible) rows of the List to get highlighted.
The following View demonstrates this behaviour: tapping or long pressing the Button or the purple area (Color View) will cause the rows in the List to get highlighted (Xcode 12.1 & iOS 14.1).
struct ContentView: View {
var body: some View {
TabView {
VStack {
List {
Text("Row 0")
Text("Row 1")
Text("Row 2")
}
.listStyle(InsetGroupedListStyle())
Spacer()
Button(action: { print("tapped")}, label: { Text("Button") } )
.padding(.vertical, 80)
Spacer()
Color.purple
}
Text("Second Page")
}
.tabViewStyle(PageTabViewStyle())
}
}
I assume this is a bug and have already submitted feedback, but was wondering if there is a workaround while it's not fixed.
wondering if there is a workaround while it's not fixed.
After some investigation & testing the only workaround I see is to use scroll view instead
TabView {
VStack {
ScrollView { // << here
Text("Row 0")
Text("Row 1")
Text("Row 2")
}
Note: of course it might require some manual formatting & layout inside scroll view, but there is no such bug.

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())
}